Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting both axes logarithmic in bar plot matploblib

I have already binned data to plot a histogram. For this reason I'm using the plt.bar() function. I'd like to set both axes in the plot to a logarithmic scale.

If I set plt.bar(x, y, width=10, color='b', log=True) which lets me set the y-axis to log but I can't set the x-axis logarithmic. I've tried plt.xscale('log') unfortunately this doesn't work right. The x-axis ticks vanish and the sizes of the bars don't have equal width.

enter image description here

I would be grateful for any help.

like image 663
aces Avatar asked May 19 '17 11:05

aces


2 Answers

By default, the bars of a barplot have a width of 0.8. Therefore they appear larger for smaller x values on a logarithmic scale. If instead of specifying a constant width, one uses the distance between the bin edges and supplies this to the width argument, the bars will have the correct width. One would also need to set the align to "edge" for this to work.

import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)

x = np.logspace(0, 5, num=21)
y = (np.sin(1.e-2*(x[:-1]-20))+3)**10

fig, ax = plt.subplots()
ax.bar(x[:-1], y, width=np.diff(x), log=True,ec="k", align="edge")
ax.set_xscale("log")
plt.show()

enter image description here

I cannot reproduce missing ticklabels for a logarithmic scaling. This may be due to some settings in the code that are not shown in the question or due to the fact that an older matplotlib version is used. The example here works fine with matplotlib 2.0.

like image 59
ImportanceOfBeingErnest Avatar answered Sep 19 '22 22:09

ImportanceOfBeingErnest


If the goal is to have equal width bars, assuming datapoints are not equidistant, then the most proper solution is to set width as plt.bar(x, y, width=c*np.array(x), color='b', log=True) for a constant c appropriate for the plot. Alignment can be anything.

like image 45
kon psych Avatar answered Sep 20 '22 22:09

kon psych