我已经将数据分箱以绘制直方图。出于这个原因,我使用plt.bar()
函数。我想将图中的两个轴设置为对数刻度。
如果我设置plt.bar(x, y, width=10, color='b', log=True)
,我可以将y轴设置为log,但我无法设置x轴对数。
我已经尝试了plt.xscale('log')
,但遗憾的是,这项工作并不正常。 x轴嘀嗒声消失,并且条的尺寸不具有相等的宽度。
如果有任何帮助,我将不胜感激。
答案 0 :(得分:4)
默认情况下,bar
绘图的条形宽度为0.8。因此,对于对数刻度上的较小x值,它们看起来较大。如果不是指定恒定宽度,而是使用bin边缘之间的距离并将其提供给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()
我不能为对数缩放重现丢失的ticklabels。这可能是由于代码中的某些设置未在问题中显示,或者是由于使用了较旧的matplotlib版本。这个例子适用于matplotlib 2.0。
答案 1 :(得分:0)
如果目标是具有相等的宽度条,假设数据点不是等距的,则最合适的解决方案是将宽度设置为
plt.bar(x, y, width=c*np.array(x), color='b', log=True)
代表适合情节的常数c
。对齐可以是任何东西。
答案 2 :(得分:0)
我知道这是一个非常老的问题,您可能已经解决了,但是我来这篇文章是因为我曾经在y轴上遇到过类似的问题,而我设法使用ax.set_ylim(df['my data'].min()+100, df['my data'].max()+100)
来解决它。在y轴上,我有一些明智的信息,我认为最好的方法是以对数刻度显示,但是当我设置对数刻度时,我看不到正确的数字(如x轴上的此帖子),所以我只保留了使用的想法记录并使用最小和最大参数。它设置我的图形的比例非常像对数。仍在寻找另一种方法不需要在set_ylim处使用-100。
答案 3 :(得分:0)
虽然这实际上并没有使用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)。