如何缩放图像的一部分并插入 matplotlib 中的同一图中

新手上路,请多包涵

我想放大一部分数据/图像并将其绘制在同一个图形中。它看起来像这个数字。

放大图

是否可以在同一图中插入一部分缩放图像。我认为可以用子图绘制另一个图形,但它绘制了两个不同的图形。我还阅读了添加补丁以插入矩形/圆形但不确定将一部分图像插入图中是否有用。我基本上从文本文件加载数据并使用如下所示的简单绘图命令对其进行绘图。

我在 这里 从 matplotlib 图片库中找到了一个相关示例,但不确定它是如何工作的。非常感谢您的帮助。

 from numpy import *
import os
import matplotlib.pyplot as plt
data = loadtxt(os.getcwd()+txtfl[0], skiprows=1)
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.semilogx(data[:,1],data[:,2])
plt.show()

原文由 Elect28 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 546
2 个回答

玩转可运行代码是学习 Python 最快的方法之一。

因此,让我们 从 matplotlib 示例库中的代码 开始。

鉴于代码中的注释,代码似乎分为 4 个主要节。第一节生成一些数据,第二节生成主要情节,第三节和第四节创建插图轴。

我们知道如何生成数据和绘制主要情节,所以让我们关注第三节:

 a = axes([.65, .6, .2, .2], axisbg='y')
n, bins, patches = hist(s, 400, normed=1)
title('Probability')
setp(a, xticks=[], yticks=[])

将示例代码复制到一个名为 test.py 的新文件中。

如果我们将 .65 更改为 .3 会发生什么?

 a = axes([.35, .6, .2, .2], axisbg='y')

运行脚本:

 python test.py

您会发现“概率”插图移到了左侧。因此 axes 函数控制插图的放置。如果您再玩一些数字,您会发现 (.35, .6) 是插图左下角的位置,而 (.2, .2) 是插图的宽度和高度。数字从 0 到 1,(0,0) 位于图的左下角。

好的,现在我们开始做饭了。在下一行我们有:

 n, bins, patches = hist(s, 400, normed=1)

您可能认为这是 用于绘制直方图的 matplotlib 命令,但如果不是,则将数字 400 更改为,比如说,10,将生成一个具有更厚实的直方图的图像,因此再次使用这些数字您很快就会发现这条线与插图中的图像有关。

您需要在此处致电 semilogx(data[3:8,1],data[3:8,2])

该行 title('Probability') 显然生成了插图上方的文本。

最后我们来到 setp(a, xticks=[], yticks=[]) 。没有数字可以玩,所以如果我们通过在行的开头放置 # 来注释整行会发生什么:

 # setp(a, xticks=[], yticks=[])

重新运行脚本。哦!现在插图轴上有很多刻度线和刻度标签。美好的。所以现在我们知道 setp(a, xticks=[], yticks=[]) 从轴上删除刻度线和标签 a

现在,理论上您有足够的信息将此代码应用于您的问题。但是还有一个潜在的绊脚石:matplotlib 示例使用 from pylab import * 而您使用 import matplotlib.pyplot as plt

matplotlib 常见问题解答import matplotlib.pyplot as plt 是在编写脚本时使用 matplotlib 的推荐方式,而 from pylab import * 用于交互式会话。所以你做的是正确的方式,(虽然我也建议使用 import numpy as np 而不是 from numpy import * )。

那么我们如何转换 matplotlib 示例以运行 import matplotlib.pyplot as plt 呢?

进行转换需要一些 matplotlib 经验。通常,您只需在像 axessetp 这样的裸名前面添加 plt. --- ,但有时函数应该来自 numpy 的调用,有时函数来自 numpy axes 对象,不是来自模块 plt 。需要经验才能知道所有这些功能的来源。谷歌搜索函数名称和“matplotlib”会有所帮助。阅读示例代码可以积累经验,但没有捷径可走。

所以,转换后的代码变成

ax2 = plt.axes([.65, .6, .2, .2], axisbg='y')
ax2.semilogx(t[3:8],s[3:8])
plt.setp(ax2, xticks=[], yticks=[])

您可以像这样在代码中使用它:

 from numpy import *
import os
import matplotlib.pyplot as plt
data = loadtxt(os.getcwd()+txtfl[0], skiprows=1)
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.semilogx(data[:,1],data[:,2])

ax2 = plt.axes([.65, .6, .2, .2], axisbg='y')
ax2.semilogx(data[3:8,1],data[3:8,2])
plt.setp(ax2, xticks=[], yticks=[])

plt.show()

原文由 unutbu 发布,翻译遵循 CC BY-SA 3.0 许可协议

最简单的方法是结合“zoomed_inset_axes”和“mark_inset”,其描述和相关示例可以在这里找到: Overview of AxesGrid toolkit

在此处输入图像描述

 import matplotlib.pyplot as plt

from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes
from mpl_toolkits.axes_grid1.inset_locator import mark_inset

import numpy as np

def get_demo_image():
    from matplotlib.cbook import get_sample_data
    import numpy as np
    f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False)
    z = np.load(f)
    # z is a numpy array of 15x15
    return z, (-3,4,-4,3)

fig, ax = plt.subplots(figsize=[5,4])

# prepare the demo image
Z, extent = get_demo_image()
Z2 = np.zeros([150, 150], dtype="d")
ny, nx = Z.shape
Z2[30:30+ny, 30:30+nx] = Z

# extent = [-3, 4, -4, 3]
ax.imshow(Z2, extent=extent, interpolation="nearest",
          origin="lower")

axins = zoomed_inset_axes(ax, 6, loc=1) # zoom = 6
axins.imshow(Z2, extent=extent, interpolation="nearest",
             origin="lower")

# sub region of the original image
x1, x2, y1, y2 = -1.5, -0.9, -2.5, -1.9
axins.set_xlim(x1, x2)
axins.set_ylim(y1, y2)

plt.xticks(visible=False)
plt.yticks(visible=False)

# 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
mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="0.5")

plt.draw()
plt.show()

原文由 kevin 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏