默认情况下,bar
图的条形宽度为0.8。因此,在对数比例尺上,较小的x值会使它们看起来更大。如果不是指定一个固定宽度,而是使用直方图边缘之间的距离并将其提供给width
参数,则条形图将具有正确的宽度。同时需要将align
设置为"edge"
才能正常工作。
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()
我无法在对数刻度下复制缺失的刻度标签。这可能是由于代码中未在问题中显示的某些设置,或由于使用了旧版matplotlib。此示例在matplotlib 2.0中正常工作。
如果目标是拥有等宽的条形图,假设数据点不是等距的,则最合适的解决方案是将宽度设置为plt.bar(x, y, width=c*np.array(x), color='b', log=True)
,其中c
是适合绘图的常数。对齐方式可以是任何东西。
我知道这是一个非常老的问题,你可能已经解决了,但我来到这篇文章是因为我遇到了类似于y轴的问题,我成功地使用ax.set_ylim(df['my data'].min()+100, df['my data'].max()+100)
解决了它。在y轴上,我有一些敏感信息,我认为最好的方法是以对数比例显示,但当我设置对数比例时,我无法正确地看到数字(就像这篇文章中的x轴),所以我放弃了使用对数的想法,使用了最小和最大参数。它设置了我的图形尺度,就像对数一样。仍在寻找另一种不需要使用-set_ylim中的-+100的方法。
虽然这并没有实际使用pyplot.bar,我认为这种方法可能对于实现OP试图完成的操作有所帮助。我发现这比尝试根据对数比例刻度来校准宽度要容易,尽管需要更多步骤。创建一个线集合,其宽度独立于图表比例。
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.collections as coll
#Generate data and sort into bins
a = np.random.logseries(0.5, 1000)
hist, bin_edges = np.histogram(a, bins=20, density=False)
x = bin_edges[:-1] # remove the top-end from bin_edges to match dimensions of hist
lines = []
for i in range(len(x)):
pair=[(x[i],0), (x[i], hist[i])]
lines.append(pair)
linecoll = coll.LineCollection(lines, linewidths=10, linestyles='solid')
fig, ax = plt.subplots()
ax.add_collection(linecoll)
ax.set_xscale("log")
ax.set_yscale("log")
ax.set_xlim(min(x)/10,max(x)*10)
ax.set_ylim(0.1,1.1*max(hist)) #since this is an unweighted histogram, the logy doesn't make much sense.
一个缺点是“条形”将会居中,但这可以通过将x值偏移半个线宽值来改变...我认为应该是
x_new = x + (linewidth/2)*10**round(np.log10(x),0)。
x[:-1]
来作为X数据来避免了一个问题,但实际数据集可能并不现实。为了纠正这个问题,你可以简单地重复最后一个bin的宽度。我创建了一个变量,并传递给width
参数:bin_widths = np.pad(np.diff(my_x_data), (0,1), mode="edge")
- astroChance