2017-06-21 61 views
3

我正在嘗試繪製兩個子圖是第一個子圖的放大圖。 我想要做的是一樣的東西下面的圖片:在子圖上繪製線以渲染縮放效果

enter image description here

特別是黑線。我對現在的代碼只是繪製次要情節

import matplotlib.pyplot as plt 
import numpy as np 

t=np.arange(1000) 
x=np.sin(np.arange(1000)/10) 

plt.figure() 
ax1 = plt.subplot(2,1,1) 
plt.plot(t,x) 

ax2 = plt.subplot(2,2,3) 
plt.plot(t[100:200],x[100:200]) 

ax3 = plt.subplot(2,2,4) 
plt.plot(t[600:700],x[600:700]) 

plt.show() 

但我不知道如何添加黑線(使縮放框效果)圖上的頂部。我不知道該如何開始。有人有想法嗎?

回答

2

其實我發現這使得很相似,我想要的東西,另一個話題:這給這個

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

def zoomingBox(ax1, roi, ax2, color='red', linewidth=2): 
    ax1.add_patch(Rectangle([roi[0],roi[2]], roi[1]-roi[0], roi[3]-roi[2],**dict([('fill',False), ('linestyle','dashed'), ('color',color), ('linewidth',linewidth)]))) 
    srcCorners = [[roi[0],roi[2]], [roi[0],roi[3]], [roi[1],roi[2]], [roi[1],roi[3]]] 
    dstCorners = ax2.get_position().corners() 
    srcBB = ax1.get_position() 
    dstBB = ax2.get_position() 
    if (dstBB.min[0]>srcBB.max[0] and dstBB.max[1]<srcBB.min[1]) or (dstBB.max[0]<srcBB.min[0] and dstBB.min[1]>srcBB.max[1]): 
     src = [0, 3]; dst = [0, 3] 
    elif (dstBB.max[0]<srcBB.min[0] and dstBB.max[1]<srcBB.min[1]) or (dstBB.min[0]>srcBB.max[0] and dstBB.min[1]>srcBB.max[1]): 
     src = [1, 2]; dst = [1, 2] 
    elif dstBB.max[1] < srcBB.min[1]: 
     src = [0, 2]; dst = [1, 3] 
    elif dstBB.min[1] > srcBB.max[1]: 
     src = [1, 3]; dst = [0, 2] 
    elif dstBB.max[0] < srcBB.min[0]: 
     src = [0, 1]; dst = [2, 3] 
    elif dstBB.min[0] > srcBB.max[0]: 
     src = [2, 3]; dst = [0, 1] 
    for k in range(2): 
     ax1.annotate('', xy=dstCorners[dst[k]], xytext=srcCorners[src[k]], xycoords='figure fraction', textcoords='data', arrowprops=dict([('arrowstyle','-'), ('color',color), ('linewidth',linewidth)])) 



t=np.arange(1000) 
x=np.sin(np.arange(1000)/10) 

plt.figure() 
ax1 = plt.subplot(2,1,1) 
plt.plot(t,x) 

ax2 = plt.subplot(2,2,3) 
plt.plot(t[100:200],x[100:200]) 

ax3 = plt.subplot(2,2,4) 
plt.plot(t[600:700],x[600:700]) 

zoomingBox(ax1, [100,200,-1.1,1.1], ax2) 
zoomingBox(ax1, [600,700,-1.1,1.1], ax3) 

plt.show() 

enter image description here

1

Use subplots to zoom into timeseries or how I can draw lines outside of axis borders

所以這裏的代碼在matplotlib頁面上執行這種軸之間的連接的示例。在這裏找到:https://matplotlib.org/users/annotations.html#zoom-effect-between-axes

適應這種以你的情況是相當直截了當:

enter image description here

from matplotlib.transforms import Bbox, TransformedBbox, blended_transform_factory 

from mpl_toolkits.axes_grid1.inset_locator import BboxPatch, BboxConnector,\ 
    BboxConnectorPatch 


def connect_bbox(bbox1, bbox2, 
       loc1a, loc2a, loc1b, loc2b, 
       prop_lines, prop_patches=None): 
    if prop_patches is None: 
     prop_patches = prop_lines.copy() 
     prop_patches["alpha"] = prop_patches.get("alpha", 1)*0.2 

    c1 = BboxConnector(bbox1, bbox2, loc1=loc1a, loc2=loc2a, **prop_lines) 
    c1.set_clip_on(False) 
    c2 = BboxConnector(bbox1, bbox2, loc1=loc1b, loc2=loc2b, **prop_lines) 
    c2.set_clip_on(False) 

    bbox_patch1 = BboxPatch(bbox1, **prop_patches) 
    bbox_patch2 = BboxPatch(bbox2, **prop_patches) 

    p = BboxConnectorPatch(bbox1, bbox2, 
          loc1a=loc1a, loc2a=loc2a, loc1b=loc1b, loc2b=loc2b, 
          **prop_patches) 
    p.set_clip_on(False) 

    return c1, c2, bbox_patch1, bbox_patch2, p 




def zoom_effect02(ax1, ax2, **kwargs): 
    """ 
    ax2 : the big main axes 
    ax1 : the zoomed axes 
    The xmin & xmax will be taken from the 
    ax1.viewLim. 
    """ 

    tt = ax1.transScale + (ax1.transLimits + ax2.transAxes) 
    trans = blended_transform_factory(ax2.transData, tt) 

    mybbox1 = ax1.bbox 
    mybbox2 = TransformedBbox(ax1.viewLim, trans) 

    prop_patches = kwargs.copy() 
    prop_patches["ec"] = "none" 
    prop_patches["alpha"] = 0.2 

    c1, c2, bbox_patch1, bbox_patch2, p = \ 
     connect_bbox(mybbox1, mybbox2, 
        loc1a=2, loc2a=3, loc1b=1, loc2b=4, 
        prop_lines=kwargs, prop_patches=prop_patches) 

    ax1.add_patch(bbox_patch1) 
    ax2.add_patch(bbox_patch2) 
    ax2.add_patch(c1) 
    ax2.add_patch(c2) 
    ax2.add_patch(p) 

    return c1, c2, bbox_patch1, bbox_patch2, p 


import matplotlib.pyplot as plt 
import numpy as np 

t=np.arange(1000) 
x=np.sin(np.arange(1000)/10.) 

plt.figure() 
ax1 = plt.subplot(2,1,1) 
plt.plot(t,x) 

ax2 = plt.subplot(2,2,3) 
plt.plot(t[100:200],x[100:200]) 
zoom_effect02(ax2, ax1) 
ax3 = plt.subplot(2,2,4) 
plt.plot(t[600:700],x[600:700]) 
zoom_effect02(ax3, ax1) 
plt.show()