简体   繁体   中英

Why is my matplotlib 2D histogram/heatmap plotted with matplotlib.imshow not matching my axes?

I am trying to create a histogram for the following data

x = [2, 3, 4, 5]
y = [1, 1, 1, 1]

I am using the following code which is, for example, described in and old version of an answer to this question about how to generate 2D histograms in matplotlib .

import matplotlib.pyplot as plt
import numpy as np

bins = np.arange(-0.5, 5.5, 1.0), np.arange(-0.5, 5.5, 1.0)
heatmap, xedges, yedges = np.histogram2d(x, y, bins=bins)
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]

plt.clf()
plt.imshow(heatmap,
           extent=extent,
           interpolation='nearest',
           cmap=plt.get_cmap('viridis'), # use nicer color map
          )
plt.colorbar()

plt.xlabel('x')
plt.ylabel('y')

However, the plot that this produces seems rotated in some way.

I was expecting this:

在此处输入图片说明

But I got

显示以意外,错误方式绘制的数据的图

Obviously, this does not match my input data. The coordinates highlighted in this plot are (1, 0), (1, 1), (1, 2), (1, 3) .

What is going on?

plt.imshow image space convention for its indexing of the input array. That is, (0, 0) in the top right corner and a y-axis that is oriented downwards.

To avoid this, you have to call plt.imshow with the optional parameter origin = 'lower' (to correct the origin) and pass the data transposed as heatmap.T to correct the flipping of the axes.

But this will not get you the correct plot yet. Not only is the origin in the wrong place, also the indexing convention is different. numpy arrays follow row/column indexing, while images usually use column/row indexing. So in addition, you have to transpose the data.

So in the end, your code should look like this:

import matplotlib.pyplot as plt
import numpy as np

bins = np.arange(-0.5, 5.5, 1.0), np.arange(-0.5, 5.5, 1.0)
heatmap, xedges, yedges = np.histogram2d(x, y, bins=bins)
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]

plt.clf()
plt.imshow(heatmap.T,
           origin='lower',
           extent=extent,
           interpolation='nearest',
           cmap=plt.get_cmap('viridis'), # use nicer color map
          )
plt.colorbar()

plt.xlabel('x')
plt.ylabel('y')

Or even better use matplotlib.pyplot.hist2d to avoid this issue completely.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM