Skip to content

Heatmap edges fix#713

Merged
swharden merged 3 commits intoScottPlot:masterfrom
StendProg:HeatMapEdgesFix
Feb 5, 2021
Merged

Heatmap edges fix#713
swharden merged 3 commits intoScottPlot:masterfrom
StendProg:HeatMapEdgesFix

Conversation

@StendProg
Copy link
Contributor

Purpose:
Current Heatmap implementation render wrong on the edges, This is especially noticeable at small Heatmaps.
This PR setup additional params for Graphics.DrawImage() to make correct edges render.
Also more accurate pixel calculation were done, as result Heatmap perfect align with axis grid.

Negative side: I remove minScale calculation, as result Heatmap cells may be not square if EqualAxis will be disabled.
All Demo already have equal axis scales, and additional math not needed.

New Functionality:
Old version (incorrect) 3x2 HeatMap from cookbook:
image

The same demo with this PR:
image

@StendProg StendProg changed the title Heat map edges fix Heatmap edges fix Jan 25, 2021
@StendProg StendProg mentioned this pull request Jan 25, 2021
@bclehmann
Copy link
Member

bclehmann commented Jan 25, 2021

Thank you for getting this working, although I'm curious about

attr.SetWrapMode(WrapMode.TileFlipXY);

It looks like this is for tiling images? But we're not trying to tile images at all.

EDIT: It looks like the only necessary line to fix this is

gfx.PixelOffsetMode = PixelOffsetMode.Half;

Now, I don't know why, but this seems to work fine.

@bclehmann
Copy link
Member

bclehmann commented Jan 25, 2021

If we only need that one line then I think one should only change what you need to. This would avoid changing the rendering of heatmaps to be stretched without being specified by the user. A one-line diff is kind of a surprising but ¯_(ツ)_/¯.

For example, RenderHeatmap can become this:

private void RenderHeatmap(PlotDimensions dims, Bitmap bmp, bool lowQuality)
{
	using (Graphics gfx = GDI.Graphics(bmp, dims, lowQuality))
	{
		gfx.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
		gfx.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;

		double minScale = Math.Min(dims.PxPerUnitX, dims.PxPerUnitY);

		if (BackgroundImage != null && !DisplayImageAbove)
			gfx.DrawImage(
				BackgroundImage,
				dims.GetPixelX(0),
				dims.GetPixelY(0) - (float)(Height * minScale),
				(float)(Width * minScale), (float)(Height * minScale));

		gfx.DrawImage(
			BmpHeatmap,
			dims.GetPixelX(0),
			dims.GetPixelY(0) - (float)(Height * minScale),
			(float)(Width * minScale),
			(float)(Height * minScale));

		if (BackgroundImage != null && DisplayImageAbove)
			gfx.DrawImage(BackgroundImage,
				dims.GetPixelX(0),
				dims.GetPixelY(0) - (float)(Height * minScale),
				(float)(Width * minScale),
				(float)(Height * minScale));
	}
}

The branch: https://github.com/Benny121221/ScottPlot/tree/heatmap-edges

The commit: bclehmann@d0eab48

@swharden swharden mentioned this pull request Jan 26, 2021
48 tasks
@StendProg
Copy link
Contributor Author

Hi @Benny121221,
You are right, PixelOffset.Half make most of the things. But if You plan plan to use different interpolation mode you need to set wrap mode too. I plan use bicubic interpolation in coordinated heat map. Maybe it not needed for base heatmap.

More accurate image coordinates also make some effect. With old ones it visible that heatmap draw 1-2 pixel less then expected on right and bottom edges.

StendProg added a commit to StendProg/ScottPlot that referenced this pull request Jan 26, 2021
@swharden swharden merged commit 899966d into ScottPlot:master Feb 5, 2021
@swharden swharden mentioned this pull request May 17, 2021
82 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants