是否可以动态控制错误条帽的大小?就像箱形图中的胡须帽一样受到控制?因此,无需将倾覆度设置为某个固定值。从以下示例中可以看到更多内容。
fig = plt.figure()
gs = gridspec.GridSpec(2, 2)
ax0 = fig.add_subplot(gs[0])
ax1 = fig.add_subplot(gs[1])
ax2 = fig.add_subplot(gs[2])
ax3 = fig.add_subplot(gs[3])
n = 3
ax0.bar(list(range(n)),
np.random.randint(1,20,n),
yerr=np.random.randn(n),
edgecolor="red",
fill=False,
capsize=5)
ax1.boxplot(np.random.normal(70, 25, (200,n)))
n = 12
ax2.bar(list(range(n)),
np.random.randint(1,20,n),
yerr=np.random.randn(n),
edgecolor="red",
fill=False,
capsize= 5)
ax3.boxplot(np.random.normal(70, 25, (200,n)))
更多的话:
是否有可能以某种方式控制相对于箱之间间距的倾覆。如果bin在所有整数上,我希望capsize的宽度为bin_center +/- 0.25
答案 0 :(得分:2)
如果我理解正确,您希望错误上限的大小自动调整到条形图的宽度,就像在箱线图中一样吗?
在这种情况下,获得所需行为的一种简单方法是将值传递给与柱数成反比的capsize=
,因为柱的数量最终将决定它们的宽度。在您对结果感到满意之前,您必须使用确切的比例系数。
fig, axs = plt.subplots(1,2, figsize=(5,2.5))
for ax,n in zip(axs,[3,12]):
ax.bar(list(range(n)),
np.random.randint(1,20,n),
yerr=np.random.randn(n),
edgecolor="red",
fill=False,
capsize=30/n) # <--- capsize inversly proportional to n
答案 1 :(得分:2)
条形图上的错误栏的上限和箱形图上的胡须上限之间存在巨大差异。晶须帽是图中的实际线(即它们具有起点和终点)。错误栏的上限是标记;与通常情节中的marker="_"
相同的标记。
因此,胡须的宽度是线的两个坐标之间的差异,而错误条帽的宽度是markersize
。 markersize
以点为单位,使其独立于图中的数据单位。这有几个优点:它们在屏幕上保持大小,与数据规模无关,在缩放图时它们保持不变,并且它们在对数刻度上看起来很好。
因此,当要求以数据单位表示错误栏大小时,您实际上是在询问如何在数据单元中缩放标记。例如,可以查看this question或this one,它们要求缩放数据单元中的分散。
因此,我们的想法是计算当前图中数据单元的点数,然后将错误栏上限的标记大小设置为此数字的倍数。
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)
fig, (ax,ax2) = plt.subplots(ncols=2, figsize=(8,4))
n = 3
bar1 = ax.bar(list(range(n)),
np.random.randint(1,20,n),
yerr=np.random.randn(n),
edgecolor="red", fill=False, capsize=1)
n = 12
bar2 = ax2.bar(list(range(n)),
np.random.randint(1,20,n),
yerr=np.random.randn(n),
edgecolor="red", fill=False, capsize=1)
class BarCapSizer():
def __init__(self, caps, size=1):
self.size=size
self.caps = caps
self.ax = self.caps[0].axes
self.resize()
def resize(self):
ppd=72./self.ax.figure.dpi
trans = self.ax.transData.transform
s = ((trans((self.size,1))-trans((0,0)))*ppd)[0]
for i,cap in enumerate(self.caps):
cap.set_markersize(s)
size = 0.5 # data units
bcs1 = BarCapSizer(bar1.errorbar.lines[1], size )
bcs2 = BarCapSizer(bar2.errorbar.lines[1], size )
plt.show()
这显示了0.5个数据单位的倾覆。问题是现在再次修复了这个问题。因此,如果交互式缩放应该保留数据单元中的标记比例,则需要使用事件处理机制来更新标记大小。这可以与here显示的内容类似。
class BarCapSizer():
def __init__(self, caps, size=1):
self.size=size
self.caps = caps
self.ax = self.caps[0].axes
self.resize()
self.cid = ax.figure.canvas.mpl_connect('draw_event', self.update)
def resize(self):
ppd=72./self.ax.figure.dpi
trans = self.ax.transData.transform
s = ((trans((self.size,1))-trans((0,0)))*ppd)[0]
for i,cap in enumerate(self.caps):
cap.set_markersize(s)
def update(self,event=None):
self.resize()
self.timer = self.ax.figure.canvas.new_timer(interval=10)
self.timer.single_shot = True
self.timer.add_callback(lambda : self.ax.figure.canvas.draw_idle())
self.timer.start()