缩放 matplotlib 中的插图,无需重新绘制数据

2023-11-22

我正在处理一些 matplotlib 图,需要有一个缩放的插图。这是可能的zoomed_inset_axes来自axes_grid1工具包。参见示例here:

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()

这将给出所需的结果:

Resulthttp://matplotlib.org/1.3.1/_images/inset_locator_demo21.png

但正如您在代码中看到的,数据必须绘制两次 - 一次用于主轴(ax.imshow...) 一次用于插入轴 (axins.imshow...).

我的问题是:

有没有办法添加缩放插图after主线剧情已经完成,without需要在新轴上再次绘制所有内容吗?

请注意:我并不是在寻找用函数包装绘图调用并让函数绘图的解决方案ax and axins(参见下面的示例),但是(如果存在)使用现有数据的本机解决方案ax。有人知道这样的解决方案是否存在吗?

这是包装解决方案:

def plot_with_zoom(*args, **kwargs):
    ax.imshow(*args, **kwargs)
    axins.imshow(*args, **kwargs)

它有效,但感觉有点像黑客,因为如果我只想放大现有绘图的某个区域,为什么我需要再次绘制所有数据。


ed-smith 回答后的一些补充说明:

上面的例子当然只是最小的例子。图中可能有许多不同的数据集(并且数据集我的意思是通过绘制的东西imshow or plotETC)。例如,想象一个包含 10 个点数组的散点图,所有点均与常见的 x 进行比较。

正如我上面所写,最直接的方法就是使用一个包装器来绘制所有实例中的数据。但我正在寻找一种从最终开始的方法(如果存在)ax对象(而不是单个绘图命令)并以某种方式创建缩放插图。


我认为以下内容可以满足您的要求。请注意,您使用返回的第一个句柄imshow并将其添加到刀片的轴上。您需要制作一份副本,以便每个图形都有一个单独的句柄,

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
import copy

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]
im = ax.imshow(Z2, extent=extent, interpolation="nearest",
          origin="lower")

#Without copy, image is shown in insert only
imcopy = copy.copy(im)
axins = zoomed_inset_axes(ax, 6, loc=1) # zoom = 6
axins.add_artist(imcopy)

# 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()

对于你的包装函数,这将是这样的,

def plot_with_zoom(*args, **kwargs):
    im = ax.imshow(*args, **kwargs)
    imcopy = copy.copy(im)
    axins.add_artist(imcopy)

然而,作为imshow只显示数组中存储的数据Z作为一个图像,我认为这个解决方案实际上会比两次单独的调用慢imshow。对于需要更多时间的绘图,例如Acontour情节或pcolormesh,这种方法可能是明智的......

EDIT:

超越单一imshow,以及不同类型的多个图。绘图函数都返回不同的句柄(例如,plot 返回线列表,imshow 返回 matplotlib.image.AxesImage 等)。您可以在绘制(或使用收藏如果它们足够相似)。然后,您可以编写一个通用函数,使用来自缩放轴的 add_artist 或 add_patch 方法将它们添加到轴,可能使用 if 类型检查来处理图中使用的各种类型。更简单的方法可能是循环ax.get_children()并重用任何不是轴本身元素的东西。

另一种选择可能是研究位块传送技术,光栅化或用于加速动画的其他技术,例如使用fig.canvas.copy_from_bbox or fig.canvas.tostring_rgb将整个图形复制为图像(请参阅为什么用 Matplotlib 绘图这么慢?‌​低)。您还可以绘制图形,将其保存为非矢量图形(使用savefig或 StringIObuffer),读回并绘制放大版本。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

缩放 matplotlib 中的插图,无需重新绘制数据 的相关文章

随机推荐

  • 使用pyspark,在hadoop文件系统上读/写2D图像

    我希望能够在 hdfs 文件系统上读取 写入图像并利用 hdfs 局部性 我有一个图像集合 其中每个图像由以下内容组成 uint16 的二维数组 存储为 xml 文件的基本附加信息 我想通过 hdfs 文件系统创建一个存档 并使用 Spar
  • jQuery Mobile 破坏了我的网站

    当我仅使用移动触摸屏设备时 我会在网站上加载 jQuery Mobile 当我这么做的时候 它把一切都搞乱了 例如 选择菜单也不能正常工作 页面底部会出现 正在加载 正在加载 未定义 字样 我知道我错过了一些东西 但不知道是什么 关于我可能
  • JavaScript 对象的生命周期和内存泄漏

    我对此进行了相当多的研究 但主要是通过将其他问题拼凑在一起 这仍然留下了一些疑问 在一个不随时刷新浏览器页面并且可能会运行相当长一段时间 几个小时 而不关闭的应用程序中 假设刷新页面或导航到另一个页面会重新启动 js 代码 确保对象的最佳方
  • TypeScript:具有可选值的可区分联合

    给定以下类型 interface FullName fullName string interface Name firstName string lastName string type Person FullName Name cons
  • 友元函数无法构造该类的唯一指针

    我有一个特定的设计策略 其中我的类的构造函数是私有的 并且只能由该类的朋友构建 在朋友函数中 我尝试使用以下命令创建我的类的 unique pointerstd make unique但它不编译 我的 VC12 编译器抱怨 c progra
  • 编写并编织一份按变量与特殊字符 (å æ ø) 分割的 PDF 报告 - 编码问题

    我尝试使用基于分组变量的部分来生成一份 PDF 报告brew and knitr 我的分组变量可能包含特殊字符 元音变音 例如 仅文档标题中的变音符号可以很好地处理 usepackage utf8 inputenc 参见下面的示例 但是 分
  • 为什么 jquery .height() 在 chrome 上得到不同的结果?

    这是 chrome 显示 div 的宽度和高度的方式 这是正确的 事实上高度是 1466 但是 如果我这样做 document ready function console log container altezza fisso heigh
  • Javascript 到 Jquery,在输入 onclick 中添加文本

    我怎样才能将这个javascript代码更改为JQuery 当用户单击链接时 文本会自动添加到输入中 这是 HTML
  • NginX 不执行 PHP

    我已经尝试过数十种可能的解决方案来解决这个问题 但找不到任何有效的解决方案 基本上 PHP 文件不会在我的 NginX PHP fpm Ubuntu 14 服务器上执行 我拥有所有软件包 并且它们正在运行 我已经清除了浏览器缓存等 但还没有
  • 重载和覆盖

    重载和覆盖有什么区别 超载 重载是指同一范围内有多个具有相同名称但不同签名的方法 Overloading public class Test public void GetStuff int id public void GetStuff
  • MVVM轻信使类

    任何人都可以提供有关如何在 MVVM Light 中使用信使类的示例 链接 简单插图 视频 演示吗 您应该查看 CodePlex 上 MVVM Light 的源代码 http mvvmlight codeplex com SourceCon
  • 仅调用一次函数

    我有 3 个 div Mask Intro Container 因此 如果您单击 蒙版 介绍 将被隐藏 而 容器 将出现 问题是我只想加载一次 而不是每次刷新页面或每次单击菜单或链接等时加载 我怎样才能做到这一点 这是我现在使用的脚本 do
  • CSS,覆盖所有选择下拉菜单的高度?

    我将如何引用 以便我可以覆盖所有选择框 以便我可以覆盖默认高度 当我使用类创建元素时我很熟悉 但我对此不确定 100 JS 解决方案 使用 jquery select height 120px 100 JS 解决方案 无 jquery va
  • 捕获组字符数限制

    假设我有这样的文字 AAAA1 AAA11 AA111AA A1111 AAAAA AAAA1111 我想找到所有符合这 3 个条件的事件 大写字母 1 至 4 次 数字1到4次 最大字符数为 5 所以比赛将是 AAAA1 AAA11 AA
  • 将数据流管道的输出写入分区目标

    我们有一个流事件源 每秒有数千个事件 这些事件都标有一个 ID 用于标识该事件属于我们数以万计的客户中的哪一个 我们希望使用此事件源来填充数据仓库 在流模式下 但是 我们的事件源不是持久的 因此我们还希望将原始数据存档在 GCS 中 以便我
  • HTML5 Canvas 使黑色透明

    我有大量黑色背景的图像 例如 是否有可能通过Javascript忽略黑色 000000 并将其绘制在画布上 出现这样的情况 基本上是尝试获取黑色像素并使其成为 Alpha 通道 因此 您需要遍历所有像素并更改所有黑色像素的 alpha 值
  • Java.util.scanner 错误处理

    我正在帮助一个朋友解决java问题 然而 我们遇到了障碍 我们使用 Java Util Scanner nextInt 从用户那里获取一个号码 不断询问用户是否提供了其他信息 唯一的问题是 我们不知道如何进行错误处理 我们尝试过的 do i
  • 使用 Google 广告通过 PhoneGap 应用获利(使用 PhoneGap Build 构建)

    在 AdMob 上 有不再有 HTML5 应用程序的选项 以及 AdSense 移动应用 甚至是基于 webview 的应用 明确提及 被禁止 如何使用 Google 广告通过 PhoneGap 应用 使用 PhoneGap Build 构
  • 未捕获的引用错误:尝试在 Chrome 中的另一个 Worker 中创建 Worker 时未定义 Worker

    This link says 如果工人们愿意的话 他们可以产生更多的工人们 所谓的副工 必须与父页面托管在同一源中 另外 子工作人员的 URI 是相对于父工作人员的 URI 进行解析的 位置而不是所属页面的位置 这使得更容易 工作人员跟踪他
  • 缩放 matplotlib 中的插图,无需重新绘制数据

    我正在处理一些 matplotlib 图 需要有一个缩放的插图 这是可能的zoomed inset axes来自axes grid1工具包 参见示例here import matplotlib pyplot as plt from mpl