虽然这实际上并不使用 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.
Resulting plot - no frills
一个缺点是“条”将居中,但这可以通过将 x 值偏移线宽值的一半来改变......我认为它会是
x_new = x + (linewidth/2)*10**round(np.log10(x),0)。