Logarithmic y-axis bins in python
Solution 1
try
plt.yscale('log', nonposy='clip')
http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.yscale
The issue is with the bottom of bars being at y=0 and the default is to mask out in-valid points (log(0)
-> undefined) when doing the log transformation (there was discussion of changing this, but I don't remember which way it went) so when it tries to draw the rectangles for you bar plot, the bottom edge is masked out -> no rectangles.
Solution 2
np.logspace returns bins in [1-10]
, logarithmically spaced - in my case xx is a npvector >0 so the following code does the trick
logbins=np.max(xx)*(np.logspace(0, 1, num=1000) - 1)/9
hh,ee=np.histogram(xx, density=True, bins=logbins)
Solution 3
The hist constructor accepts the log
parameter.
You can do this:
plt.hist(data, bins=bins, log=True)
Comments
-
mannaroth almost 2 years
I'm trying to create a histogram of a data column and plot it logarithmically (
y-axis
) and I'm not sure why the following code does not work:import numpy as np import matplotlib.pyplot as plt data = np.loadtxt('foo.bar') fig = plt.figure() ax = fig.add_subplot(111) plt.hist(data, bins=(23.0, 23.5,24.0,24.5,25.0,25.5,26.0,26.5,27.0,27.5,28.0)) ax.set_xlim(23.5, 28) ax.set_ylim(0, 30) ax.grid(True) plt.yscale('log') plt.show()
I've also tried instead of
plt.yscale('log')
addingLog=true
in theplt.hist
line and also I triedax.set_yscale('log')
, but nothing seems to work. I either get an empty plot, either they-axis
is indeed logarithmic (with the code as shown above), but there is no data plotted (no bins). -
mannaroth almost 11 yearsThanks for the answer. The solution you proposed solved the disappearing bars, but another "bug" then surfaced: all the labels of the y-logarithmic axis were plotted on top of each other. This last problem was solved by commenting the "ax.set_ylim(0, 30)" line.
-
tacaswell almost 11 yearsyes, because the 0 in the limit is clipped to some very small number so you have an unreasonable number of decades. use
ax.set_ylim(1, 30)
instead.