如何使用轴位置作为参考在matplotlib上跨多个轴绘制框

时间:2019-04-23 15:34:08

标签: python matplotlib

我想使用一个斧头坐标作为参考跨多个轴绘制一个框。我有没有生成框的简单代码是

import matplotlib.pyplot as plt
import numpy as np

fig, (ax1, ax2) = plt.subplots(2, 1, sharex=False, sharey=False, figsize=(15,9))

x = 2 * np.pi * np.arange(1000) / 1000 
y1 = np.sin(x)
y2 = np.cos(x)

ax1.plot(x,y1)
ax2.plot(x,y2)
plt.show()

这将产生下图:

enter image description here

我想要的是下图,使用来自ax2的x坐标来指定位置:

enter image description here

2 个答案:

答案 0 :(得分:1)

肯定有一个使用Rectangle补丁的简单方法,但这暂时是一种解决方法。这个想法是要有4条线:2条水平线分别限制为ax1ax2,2条垂直线同时跨越ax1ax2。对于后两个,使用ConnectionPatch覆盖两个轴。要使用水平线和垂直线的y值的上和下值,请使用get_ylim()函数。绘制垂直线的想法来自this官方示例和this

ImportanceOfBeingErnest 答案
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import ConnectionPatch

fig, (ax1, ax2) = plt.subplots(2, 1, sharex=False, sharey=False, figsize=(15,9))

x = 2 * np.pi * np.arange(1000) / 1000 
y1 = np.sin(x)
y2 = np.cos(x)

ax1.plot(x,y1)
ax2.plot(x,y2)

y_up, y_down = ax1.get_ylim(), ax2.get_ylim()

ax1.hlines(max(y_up), 1, 2, linewidth=4)
ax2.hlines(min(y_down), 1, 2, linewidth=4)

line1 = ConnectionPatch(xyA=[1,min(y_down)], xyB=[1,max(y_up)], coordsA="data", coordsB="data",
                      axesA=ax2, axesB=ax1, color="k", lw=4)
line2 = ConnectionPatch(xyA=[2,min(y_down)], xyB=[2,max(y_up)], coordsA="data", coordsB="data",
                      axesA=ax2, axesB=ax1, color="k", lw=4)

ax2.add_artist(line1)
ax2.add_artist(line2)

plt.show()

enter image description here

答案 1 :(得分:1)

问题是矩形应该起到什么作用。如果它只是绑定到ax2的矩形,但一直延伸到ax1的上边缘,则可以像这样创建矩形

import matplotlib.pyplot as plt
import numpy as np

fig, (ax1, ax2) = plt.subplots(2, 1, sharex=False, sharey=False, figsize=(15,9))

x = 2 * np.pi * np.arange(1000) / 1000 
y1 = np.sin(x)
y2 = np.cos(x)

ax1.plot(x,y1)
ax2.plot(x,y2)

rect = plt.Rectangle((1,0), width=1, height=2+fig.subplotpars.wspace,
                     transform=ax2.get_xaxis_transform(), clip_on=False,
                     edgecolor="k", facecolor="none", linewidth=3)
ax2.add_patch(rect)

plt.show()

enter image description here

但是,即使ax1的限制发生了变化,这也将保持不变。那是想要的吗?

因此,也许更有趣的解决方案是矩形遵循两个轴上的坐标。以下内容仅适用于matplotlib 3.1,该版本截至今天仅可作为预发行版
pip install --pre --upgrade matplotlib

import matplotlib.pyplot as plt
from matplotlib.patches import ConnectionPatch
import numpy as np

fig, (ax1, ax2) = plt.subplots(2, 1, sharex=False, sharey=False, figsize=(15,9))

x = 2 * np.pi * np.arange(1000) / 1000 
y1 = np.sin(x)
y2 = np.cos(x)

ax1.plot(x,y1)
ax2.plot(x,y2)

def rectspan(x1, x2, ax1, ax2, **kwargs):
    line1, = ax1.plot([x1, x1, x2, x2],[0,1,1,0], 
                      transform=ax1.get_xaxis_transform(), **kwargs)
    line2, = ax2.plot([x1, x1, x2, x2],[1,0,0,1], 
                      transform=ax2.get_xaxis_transform(), **kwargs)
    for x in (x1, x2):
        p = ConnectionPatch((x,1), (x,0), 
                            coordsA=ax2.get_xaxis_transform(),
                            coordsB=ax1.get_xaxis_transform(), **kwargs)
        ax1.add_artist(p)

rectspan(1, 2, ax1, ax2, color="k", linewidth=3)
plt.show()

enter image description here