3

I'm having two lists x, y representing coordinates in 2D. For example x = [1,4,0.5,2,5,10,33,0.04] and y = [2,5,44,0.33,2,14,20,0.03]. x[i] and y[i] represent one point in 2D. Now I also have a list representing "heat" values for each (x,y) point, for example z = [0.77, 0.88, 0.65, 0.55, 0.89, 0.9, 0.8,0.95]. Of course x,y and z are much higher dimensional than the example.

Now I would like to plot a heat map in 2D where x and y represents the axis coordinates and z represents the color. How can this be done in python?

Lee
  • 29,398
  • 28
  • 117
  • 170
machinery
  • 5,972
  • 12
  • 67
  • 118
  • 2
    Check out tricontour in matplotlib. Here's an example from their gallery: http://matplotlib.org/examples/pylab_examples/tricontour_demo.html – Brian Jan 31 '17 at 16:12

2 Answers2

5

This code produces a heat map. With a few more data points, the plot starts looking pretty nice and I've found it to be very quick in general even for >100k points.

import matplotlib.pyplot as plt
import matplotlib.tri as tri
import numpy as np
import math

x = [1,4,0.5,2,5,10,33,0.04]
y = [2,5,44,0.33,2,14,20,0.03]
z = [0.77, 0.88, 0.65, 0.55, 0.89, 0.9, 0.8, 0.95]
levels = [0.7, 0.75, 0.8, 0.85, 0.9]

plt.figure()
ax = plt.gca()
ax.set_aspect('equal')
CS = ax.tricontourf(x, y, z, levels, cmap=plt.get_cmap('jet'))
cbar = plt.colorbar(CS, ticks=np.sort(np.array(levels)),ax=ax, orientation='horizontal', shrink=.75, pad=.09, aspect=40,fraction=0.05)
cbar.ax.set_xticklabels(list(map(str,np.sort(np.array(levels)))))  # horizontal colorbar
cbar.ax.tick_params(labelsize=8) 
plt.title('Heat Map')
plt.xlabel('X Label')
plt.ylabel('Y Label')

plt.show()

Produces this image:

enter image description here

or if you're looking for a more gradual color change, change the tricontourf line to this:

CS = ax.tricontourf(x, y, z, np.linspace(min(levels),max(levels),256), cmap=cmap)

and then the plot will change to:

enter image description here

Brian
  • 1,988
  • 1
  • 14
  • 29
2

Based on this answer, you might want to do something like:

import numpy as np
from matplotlib.mlab import griddata
import matplotlib.pyplot as plt 
xs0 = [1,4,0.5,2,5,10,33,0.04]
ys0 = [2,5,44,0.33,2,14,20,0.03]
zs0 = [0.77, 0.88, 0.65, 0.55, 0.89, 0.9, 0.8,0.95]   
N = 30j
extent = (np.min(xs0),np.max(xs0),np.min(ys0),np.max(ys0))  
xs,ys = np.mgrid[extent[0]:extent[1]:N, extent[2]:extent[3]:N]    
resampled = griddata(xs0, ys0, zs0, xs, ys, interp='linear')   
plt.imshow(np.fliplr(resampled).T, extent=extent,interpolation='none')
plt.colorbar()

enter image description here

The example here might also help: http://matplotlib.org/examples/pylab_examples/griddata_demo.html

Community
  • 1
  • 1
Lee
  • 29,398
  • 28
  • 117
  • 170
  • Very nice answer re! But some details I want to know: when I plot it, I can not move the x length as regard to they won. They stay stacked to the "mathematical" proportion (I hope to be clear...). It can be very problematic if x and y have some orders of magnitude of difference. And also, can you replace "N" by a normal number that we could change as a variable? A Nx and NY would be nice! Thanks – Agape Gal'lo Oct 12 '18 at 19:24