Plots; pythonplot(): approximate heatmap as gradients to save space


Is it possible to turn a heatmap from individual pixels into something that’s a little easier on storage? Especially, if nothing very exciting is happening in most places of the heatmap, a collection of gradients could convey the same data (minus ugly pixelation). The idea is to get something that looks smooth and pretty rather than ugly and pixely, but at the same time doesn’t need to store a large number of rectangles of fixed color for each data point.
As a simple example, a linear combination of x and y as a heatmap would be sufficiently described by a single rectangle with a color gradient. Of course, my heatmap isn’t that simple, so I’d need multiple shapes with multiple gradients.

Thanks for your reply. However, I need a heatmap plot with axes etc. and export it as an image (preferably vector graphics). I suppose just embedding the heatmap as pixel graphics in the svg export would already be an improvement in terms of storage.

Seems the gr backend stores the heatmap as a bitmap, so instead of a 1.5 MB image, I just have a 71 kB image.

The problem is that I’m using the pythonplot backend for all my other plots because of a bug in the gr backend that doesn’t support logarithmic scaling of the colorbar. Using different backends is not pretty at all. So if you could tell me how to make pythonplot store heatmaps as bitmaps, I’d be happy I guess :slight_smile:

though some complex gradient would be even better, because there’d be no pixels at all.

i.e. you want to compress an image by dividing it into blocks and representing each block approximately by a small number of basis functions (e.g. degree-1 polynomials). This is, of course, exactly what JPEG does (albeit with cosines rather than polynomial basis functions).

In principle, SVG can embed JPEG images, but I don’t know how to make Matplotlib rasterize a heatmap in an SVG using JPEG compression while keeping vector graphics for the rest?

It wouldn’t have to be jpeg, a simple, uncompressed bitmap would be better than each pixel being represented by its four corners and a color - all in ascii-converted floats.

In the absence of a MWE with code, it might be helpful to include an image of your heatmap, with all the scales (x, y and values).

OK, maybe this is an easy one, but I just cannot figure out how to convert a matrix to an image using a color gradient.

Not easy to understand.

See if this example means something:

using Plots
x = range(-20, 20, 100); y = 2*x
m = sin.(x .* y')
c = cgrad([:red,:yellow,:green])
heatmap(x, y, m, color=c, clims=(-1,1))

Sorry for my late reply and thanks for yours. I would have to include the raster image in a plot made by the pythonplot backend, just exporting to an image is not sufficient.

However, I have figured that a contour plot probably fits my use case better, because the change of z is gradual and strictly increasing across both axes so I only have one line per level. It’s also easier to read because matching two colors is harder than reading a value.