Reputation: 2327
I have the results of a (H,ranges) = numpy.histogram2d()
computation and I'm trying to plot it.
Given H
I can easily put it into plt.imshow(H)
to get the corresponding image. (see http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.imshow )
My problem is that the axis of the produced image are the "cell counting" of H
and are completely unrelated to the values of ranges.
I know I can use the keyword extent
(as pointed in: Change values on matplotlib imshow() graph axis ). But this solution does not work for me: my values on range
are not growing linearly (actually they are going exponentially)
My question is: How can I put the value of range
in plt.imshow()
? Or at least, or can I manually set the label values of the plt.imshow
resulting object?
Editing the extent
is not a good solution.
Upvotes: 7
Views: 16941
Reputation: 87376
Expanding a bit on @thomas answer
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mi
im = np.random.rand(20, 20)
ticks = np.exp(np.linspace(0, 10, 20))
fig, ax = plt.subplots()
ax.pcolor(ticks, ticks, im, cmap='viridis')
ax.set_yscale('log')
ax.set_xscale('log')
ax.set_xlim([1, np.exp(10)])
ax.set_ylim([1, np.exp(10)])
By letting mpl take care of the non-linear mapping you can now accurately over-plot other artists. There is a performance hit for this (as pcolor
is more expensive to draw than AxesImage
), but getting accurate ticks is worth it.
Upvotes: 8
Reputation: 69116
You can just change the tick labels to something more appropriate for your data.
For example, here we'll set every 5th pixel to an exponential function:
import numpy as np
import matplotlib.pyplot as plt
im = np.random.rand(21,21)
fig,(ax1,ax2) = plt.subplots(1,2)
ax1.imshow(im)
ax2.imshow(im)
# Where we want the ticks, in pixel locations
ticks = np.linspace(0,20,5)
# What those pixel locations correspond to in data coordinates.
# Also set the float format here
ticklabels = ["{:6.2f}".format(i) for i in np.exp(ticks/5)]
ax2.set_xticks(ticks)
ax2.set_xticklabels(ticklabels)
ax2.set_yticks(ticks)
ax2.set_yticklabels(ticklabels)
plt.show()
Upvotes: 9
Reputation: 1813
imshow
is for displaying images, so it does not support x and y bins.
You could either use pcolor
instead,
H,xedges,yedges = np.histogram2d()
plt.pcolor(xedges,yedges,H)
or use plt.hist2d
which directly plots your histogram.
Upvotes: 5