繁体   English   中英

将线更改为插入轴

[英]Changing lines to inset axes

我正在使用 matplotlib v. 3.0.3。 我想使用插入轴放大 imshow plot 中的位置,然后 plot 放大主图像之外的部分。 我正在使用以下代码玩插入轴

import matplotlib.pyplot as plt
import numpy as np
#from mpl_toolkits.axes_grid1.inset_locator import (inset_axes, InsetPosition, mark_inset)

fig, ax = plt.subplots(figsize=(6,6))
Z2 = np.random.rand(512, 512)

ax.imshow(Z2, interpolation='gaussian', cmap = 'RdBu', origin='lower')
ax.tick_params(axis='both', bottom=False, top=False, right=False, left=False, labelbottom=False, labelleft=False, labeltop=False, labelright=False)

# inset axes...
axins_1 = ax.inset_axes([0, -1, 1, 1]) # bottom left, outside main plot
axins_1.imshow(Z2, interpolation="gaussian", cmap = 'RdBu', origin='lower')
axins_1.tick_params(axis='both', bottom=False, top=False, right=False, left=False, labelbottom=False, labelleft=False, labeltop=False, labelright=False)
# sub region of the original image
axins_1.set_xlim(100, 150)
axins_1.set_ylim(85, 135)

ax.indicate_inset_zoom(axins_1, edgecolor='0')
#mark_inset(ax, axins_1, loc1=2, loc2=3, fc="none", lw=1, ec='k')

# inset axes...
axins_2 = ax.inset_axes([1, -1, 1, 1]) # bottom right, outside main plot
axins_2.imshow(Z2, interpolation="gaussian", cmap = 'RdBu', origin='lower')
axins_2.tick_params(axis='both', bottom=False, top=False, right=False, left=False, labelbottom=False, labelleft=False, labeltop=False, labelright=False)
# sub region of the original image
axins_2.set_xlim(400, 450)
axins_2.set_ylim(200, 250)

ax.indicate_inset_zoom(axins_2, edgecolor='0')
#mark_inset(ax, axins_2, loc1=2, loc2=3, fc="none", lw=1, ec='k')

# inset axes...
axins_3 = ax.inset_axes([1, 0, 1, 1]) # top right, outside main plot
axins_3.imshow(Z2, interpolation="gaussian", cmap = 'RdBu', origin='lower')
axins_3.tick_params(axis='both', bottom=False, top=False, right=False, left=False, labelbottom=False, labelleft=False, labeltop=False, labelright=False)
# sub region of the original image
axins_3.set_xlim(400, 450)
axins_3.set_ylim(400, 450)

ax.indicate_inset_zoom(axins_3, edgecolor='0')
#mark_inset(ax, axins_3, loc1=2, loc2=3, fc="none", lw=1, ec='k')

plt.show()

在这里,主要的 plot 是左上角,而右上角和两个底部图片是放大的数量。 这几乎完全生成了我在 Jupyter notebook 中所追求的 plot 但是,我有两个问题要解决。

我的第一个问题是,当我保存 plot 时,结果如下

在此处输入图像描述

这清楚地切断了缩放的图像。 我想知道如何解决这个问题?

第二个问题是从主要 plot 的子部分到缩放图像的线条在多个地方交叉。 我想要的是保留小节周围的框,但改变线条。 但是,从文档看来,您不能只删除线条,因为更改 edgecolor 会同时为框和线条着色。

我想要的是有一个从该部分指向正确的缩放图像的箭头,或者以其他方式标记这些部分及其相应的缩放图像。 但是,我还没有找到一种方法来做到这一点。 这可能吗? 如果是这样,我们该怎么做?

另一种方法是制作子图,并简单地 plot 子图中的缩放区域。 但是,在这种方法中,我不知道如何用相应的缩放 plot 来识别每个小节。

您可以随时滚动您自己的简化inset function。

在这里,我使用subplots来控制我的布局,以帮助确保我不会在我的Figure边界之外绘制(这就是为什么你的Figure在保存到文件时会剪辑你的Axes )。

此外,我设置了我自己的矩形和ConnectionPatch ,这样我只需使用我需要的 arguments 为每个所需的插图绘制一个ConnectionPatch 这使我能够明确控制箭头的开始和结束位置。

在我提供的 function

  • arrow_start是矩形上比例单位的 xy 坐标(例如 (0, 0) 是矩形的左下角, (0, .5) 是左中角, (0, 1) 是左上角, ( 1, 1) 是右上角,等等。
  • arrow_end是插入轴上比例单位的 xy 坐标(例如 (0, 0) 是插入轴的左下角,依此类推。

您可以使用这两个参数明确地将箭头放置在您认为它们 go 最好的位置,以免与其他Axes重叠

我还将您的一些样式设置代码移到顶部作为要使用的默认设置。

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

plt.rc('xtick', bottom=False, top=False, labelbottom=False)
plt.rc('ytick', left=False, right=False, labelleft=False)
plt.rc('figure', facecolor='white')

def indicate_inset(axin, axout, arrow_start=(0, 0), arrow_end=(0, 0)):
    (x0, x1), (y0, y1) = axin.get_xlim(), axin.get_ylim()
    width = x1 - x0
    height = y1 - y0
    
    rect = Rectangle(
        [x0, y0], width=width, height=height, 
        transform=axout.transData, fc='none', ec='black'
    )
    axout.add_patch(rect)
    
    conn = ConnectionPatch(
        xyA=arrow_start, coordsA=rect.get_transform(),
        xyB=arrow_end, coordsB=axin.transAxes,
        arrowstyle='->'
    )
    fig.add_artist(conn)
    return rect, conn


fig, axes = plt.subplots(
    2, 2, figsize=(6, 6), 
    gridspec_kw={'wspace': 0.05, 'hspace': 0.05, 'left':.1, 'right': .9}
)
Z2 = np.random.rand(512, 512)

imshow_kws = dict(interpolation='gaussian', cmap='RdBu', origin='lower')
raw_ax = axes[0, 0]
raw_ax.imshow(Z2, **imshow_kws)

# inset axes...
axes[1, 0].imshow(Z2, **imshow_kws)
axes[1, 0].set(xlim=(100, 150), ylim=(85, 135))
indicate_inset(axes[1, 0], raw_ax, arrow_start=(.5, 0), arrow_end=(.5, 1))

# # inset axes...
axes[1, 1].imshow(Z2, **imshow_kws)
axes[1, 1].set(xlim=(400, 450), ylim=(200, 250))
indicate_inset(axes[1, 1], raw_ax, arrow_start=(.5, 0), arrow_end=(0, 1))

# # # inset axes...
axes[0, 1].imshow(Z2, **imshow_kws)
axes[0, 1].set(xlim=(400, 450), ylim=(400, 450))
indicate_inset(axes[0, 1], raw_ax, arrow_start=(1, 0), arrow_end=(0, .5))

fig.savefig('test.png') # This is the image uploaded to this answer

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM