heatmap in matplotlib with vector format
Asked Answered
C

1

8

I'm trying to use matplotlib to plot 3D heatmap with results of my simulations. I've read this topic and tried to use imshow. Unfortunately, when I save the figure in SVG or EPS formats, it converts heatmat to picture (which isn't acceptable for journal). So, I've tried hexbin also - but image is so weird. I'm not sure it will be accepted by journal. Do we have something else, or I have to fill heatmat by rectangles?

For example, if one runs this code:

import numpy as np
import numpy.random
import matplotlib.pyplot as plt

# Generate some test data
x = np.random.randn(8873)
y = np.random.randn(8873)

heatmap, xedges, yedges = np.histogram2d(x, y, bins=50)
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]

print extent
print heatmap
plt.clf()
surf = plt.imshow(heatmap, extent=extent)
plt.colorbar(surf, shrink=0.75, aspect=5)
plt.show()

and save SVG file, it will containe PNG image:

   <g clip-path="url(#p6def4f5150)">
    <image height="347" width="315" x="115.127800906" xlink:href="data:image/png;base64,

I use matplotlib, version 1.1.1 under OpenSUSE and Ubuntu OS.

Crescendo answered 31/5, 2013 at 19:21 Comment(1)
@tcaswell I've edited main topicCrescendo
P
11

Use pcolormesh where you're using imshow if you want vector output.

When using pcolor or pcolormesh you can't interpolate the image, however. On the other hand, you probably don't want interpolation if you're wanting vector output.

That's basically the reason for the difference between imshow and pcolor/pcolormesh. imshow produces a raster, while pcolormesh and pcolor produce rectangular patches.

You'll also need to slightly change the way you pass in the extent of the image. As an example based on yours:

import numpy as np
import numpy.random
import matplotlib.pyplot as plt

# Generate some test data
x = np.random.randn(8873)
y = np.random.randn(8873)

heatmap, xedges, yedges = np.histogram2d(x, y, bins=50)

surf = plt.pcolormesh(xedges, yedges, heatmap)
plt.axis('image')
plt.colorbar(surf, shrink=0.75, aspect=5)
plt.show()

enter image description here

When you save as an svg, the output will be vector patches. E.g.

...
   <g id="QuadMesh_1">
    <defs>
     <path d="
M75.9063 -43.2
L82.9705 -43.2
L82.9705 -50.112
L75.9063 -50.112
L75.9063 -43.2" id="C0_0_9d1ab33858"/>
     <path d="
M82.9705 -43.2
L90.0348 -43.2
L90.0348 -50.112
L82.9705 -50.112
L82.9705 -43.2" id="C0_1_d828245e6a"/>
...
Posse answered 31/5, 2013 at 21:15 Comment(2)
thanks! it works! :) Can you explain what this: 'plt.axis('image')'?Crescendo
It sets the aspect ratio of the plot to 1 (i.e. square pixels will be square) and trims the limits in. It's just there so that the output will look similar to imshow.Posse

© 2022 - 2024 — McMap. All rights reserved.