簡體   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