我正在尝试绘制水平射线而不是水平线。 Matplotlib具有axhline()函数。但是它从图表的开头开始绘制。正如您在所附图片中看到的那样,我在条形图的高低处设置点。
有没有办法在特定点上画一条线?
我尝试过fillstyle="right"
,但我认为这不是我想要的。
答案 0 :(得分:-2)
是的,可以使用plt.axhline
绘制水平射线。例如,以下代码生成具有水平射线的箱形图:
import matplotlib.pyplot as plt
import numpy as np
mu, sigma = 50, 25
value1 = 1.5*mu + sigma*np.random.randn(100)
value2 = mu + 1.5*sigma*np.random.randn(100)
value3 = 0.5*mu + sigma*np.random.randn(100)
value4 = mu + 0.5*sigma*np.random.randn(100)
box_plot_data=[value1,value2,value3,value4]
plt.boxplot(box_plot_data)
plt.axhline(y=90, xmin=0.380, xmax=1)
plt.show()
数据是随机的,颜色是默认值,但是想法是一样的。默认箱形图上的xrange
是[0, 1]
,每个箱形图均分成相等的区域。每个框位于其区域的中心,因此四个框的中心位于0.125、0.375,.625和0.875。
要在第二个箱形图的右边绘制一条水平线,可以使xmin
的值大约为0.375。我说大概是因为matplotlib会根据线宽略微过度扩展,因此通常最好添加0.005(或一个数字,具体取决于您在axhline中使用的线宽)。这就是为什么我实际上使用xmin=0.380
而不是xmin=0.375
的原因。
答案 1 :(得分:-2)
我认为最简单的方法是绘制从(n,y0)
到(xend,y0)
的线,其中xend
是轴右边缘的坐标。可能会发现例如通过
xstart, xend = ax.get_xlim()
之后绘制了箱线图。 n
是箱线图编号,y0
是绘制线的y坐标(我想后者是已知的吗?)
对于n=2
和y0=90
,绘制直线是直接的,
ax.plot([2,xend],[90,90])
完整示例(接管@davidlowryduda的答案中的箱线图例):
import numpy as np
import matplotlib.pyplot as plt
mu, sigma = 50, 25
value1 = 1.5*mu + sigma*np.random.randn(100)
value2 = mu + 1.5*sigma*np.random.randn(100)
value3 = 0.5*mu + sigma*np.random.randn(100)
value4 = mu + 0.5*sigma*np.random.randn(100)
box_plot_data=[value1,value2,value3,value4]
fig,ax = plt.subplots()
ax.boxplot(box_plot_data)
xstart, xend = ax.get_xlim()
ax.plot([2,xend],[90,90])
plt.show()
这样做的缺点是缩放或平移时不会保留该行。如果需要的话,需要使用a callback。
import numpy as np
import matplotlib.pyplot as plt
mu, sigma = 50, 25
value1 = 1.5*mu + sigma*np.random.randn(100)
value2 = mu + 1.5*sigma*np.random.randn(100)
value3 = 0.5*mu + sigma*np.random.randn(100)
value4 = mu + 0.5*sigma*np.random.randn(100)
box_plot_data=[value1,value2,value3,value4]
fig,ax = plt.subplots()
ax.boxplot(box_plot_data)
xstart, xend = ax.get_xlim()
line, = ax.plot([2,xend],[90,90])
def callback(evt):
xstart, xend = ax.get_xlim()
line.set_xdata((2,xend))
ax.callbacks.connect('xlim_changed', callback)
plt.show()
通过此操作,即使缩放或平移后,线条仍保持在应有的位置。
另一种选择是增强ConnectionPatch
以允许任意变换,这样您就可以提供将x
坐标作为轴坐标,将y坐标作为坐标的变换数据坐标。此转换由ax.get_yaxis_transform()
给出。借助下面显示的子类ConnectionPatch
,无需回调即可实现与上述相同的功能。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import ConnectionPatch
class EnhancedConnector(ConnectionPatch):
def _get_xy(self, x, y, s, axes=None):
p = super()._get_xy(x, y, s, axes=axes)
if p is None:
return s.transform_point((x, y))
else:
return p
mu, sigma = 50, 25
value1 = 1.5*mu + sigma*np.random.randn(100)
value2 = mu + 1.5*sigma*np.random.randn(100)
value3 = 0.5*mu + sigma*np.random.randn(100)
value4 = mu + 0.5*sigma*np.random.randn(100)
box_plot_data=[value1,value2,value3,value4]
fig,ax = plt.subplots()
ax.boxplot(box_plot_data)
transB = ax.get_yaxis_transform()
p = EnhancedConnector(xyA=(2,90), xyB=(1,90), coordsA="data", coordsB=transB,
axesA=ax, axesB=ax)
ax.add_patch(p)
plt.show()