Let's say we would like to do a heatmap from three 1D arrays x, y, z. The answer from Plotting a heat map from three lists: X, Y, Intensity works, but the Z = np.array(z).reshape(len(y), len(x)) line highly depends from the order in which the z-values have been added to the list.
As an example, the 2 following tests give the exact same plot, whereas it should not. Indeed:
in test1,
z=2should be forx=100, y=7.in test2,
z=2should be forx=102, y=5.
How should we create the Z matrix in the function heatmap, so that it's not dependent on the
order in which z-values are added?
import numpy as np
import matplotlib.pyplot as plt
def heatmap(x, y, z):
z = np.array(z)
x = np.unique(x)
y = np.unique(y)
X, Y = np.meshgrid(x, y)
Z = np.array(z).reshape(len(y), len(x))
plt.pcolormesh(X, Y, Z)
plt.show()
### TEST 1
x, y, z = [], [], []
k = 0
for i in range(100, 120):
for j in range(5, 15):
x.append(i)
y.append(j)
z.append(k)
k += 1
heatmap(x, y, z)
### TEST 2
x, y, z = [], [], []
k = 0
for j in range(5, 15):
for i in range(100, 120):
x.append(i)
y.append(j)
z.append(k)
k += 1
heatmap(x, y, z)
Edit: Example 2: Let's say
x = [0, 2, 1, 2, 0, 1]
y = [3, 4, 4, 3, 4, 3]
z = [1, 2, 3, 4, 5, 6]
There should be a non-ambiguous way to go from the 3 arrays x, y, z to a heatmap-plottable meshgrid + a z-value matrix, even if x and y are in random order.
In this example x and y are in no particular order, quite random. How to do this?
Here a reshape like Z = np.array(z).reshape(len(y), len(x)) would be in wrong order.
If you look into
np.meshgrid, you will see that there are two indexing schemes,"xy"(the default) and"ij". When using"xy"indexing,X(thenp.meshgridresult) increases along the columns andYincreases along the rows. This is the opposite of"ij"indexing whereXincrease along the rows andYacross the columns.In your Test 1, if you were to reshape
xusing the typical c-style ordering (np.reshape(x, (20, 10))), you'd see that the resulting array increases along the rows, so it is using"ij"(andyincreases along the columns). In your Test 2, the reshape (np.reshape(x, (10, 20))) would result in the reshapedxincreasing along the columns, so it is using"xy"indexing.That said, you can adjust your
heatmapfunction call to take a parameter for which indexing to use when callingnp.meshgridand also reshapeZto be the same shape asX/Y.Edit:
To handle the case with random-ordered data, you can deal with it by sorting along
xandyin the proper order to achieve the desired indexing result.You can test it on your sample input like so: