我想在一个子图中绘制阻尼随机游走的时间序列,然后在第二个子图中放大它。我mark_inset从matplotlib知道,效果很好。到目前为止,我的代码是:
mark_inset
from mpl_toolkits.axes_grid1.inset_locator import mark_inset from astroML.time_series import generate_damped_RW fig = plt.figure() ax = fig.add_subplot(111) ax0 = fig.add_subplot(211) ax1 = fig.add_subplot(212) ax.set_ylabel('Brightness[mag]') ax.yaxis.labelpad=30 ax.spines['top'].set_color('none') ax.spines['bottom'].set_color('none') ax.spines['left'].set_color('none') ax.spines['right'].set_color('none') ax.tick_params(labelcolor='w', top='off', bottom='off', left='off', right='off') t = np.linspace(0, 5000, 100000) data = generate_damped_RW(t, tau=100, xmean=20, z=0, SFinf=0.3, random_state=1) ax0.scatter(t, data, s=0.5) ax0.text(1, 1, r'$E(m) = %.2f, \sigma(m) = %.2f$'%(np.mean(data), np.std(data)), verticalalignment='top', horizontalalignment='right', transform=ax0.transAxes, fontsize=23) mask = (t > 370) & (t < 470) ax1.set_xlabel('Time[years]') ax1.scatter(t[mask], data[mask], s=0.5) mark_inset(ax0, ax1, loc1=2, loc=1, fc='none')
这将创建如下图:
这几乎是我想要的,除了连接2个子图的线从第一个子图中的框的上边缘开始。是否有可能从第二个子图中的较低的两个边缘开始,而仍然在第二个子图中的较高的两个边缘处结束呢?我要怎么做才能做到这一点?
在mark_inset有两个参数loc1,并loc2设置两个连接器的位置。这样,盒子和插入轴的位置相同。
loc1
loc2
但是,我们可以在mark_inset函数中添加两个新参数,以为连接器的开始和结束设置不同的位置。
import matplotlib.pyplot as plt from mpl_toolkits.axes_grid1.inset_locator import TransformedBbox, BboxPatch, BboxConnector import numpy as np fig, (ax, axins) = plt.subplots(nrows=2) x = np.linspace(0,6*np.pi) y = np.sin(x) ax.plot(x,y) axins.plot(x,y) axins.set_xlim((2*np.pi, 2.5*np.pi)) axins.set_ylim((0, 1)) # draw a bbox of the region of the inset axes in the parent axes and # connecting lines between the bbox and the inset axes area # loc1, loc2 : {1, 2, 3, 4} def mark_inset(parent_axes, inset_axes, loc1a=1, loc1b=1, loc2a=2, loc2b=2, **kwargs): rect = TransformedBbox(inset_axes.viewLim, parent_axes.transData) pp = BboxPatch(rect, fill=False, **kwargs) parent_axes.add_patch(pp) p1 = BboxConnector(inset_axes.bbox, rect, loc1=loc1a, loc2=loc1b, **kwargs) inset_axes.add_patch(p1) p1.set_clip_on(False) p2 = BboxConnector(inset_axes.bbox, rect, loc1=loc2a, loc2=loc2b, **kwargs) inset_axes.add_patch(p2) p2.set_clip_on(False) return pp, p1, p2 mark_inset(ax, axins, loc1a=1, loc1b=4, loc2a=2, loc2b=3, fc="none", ec="crimson") plt.draw() plt.show()