【问题标题】:How do I re-draw only one set of axes on a figure in python?如何在 python 中的图形上仅重新绘制一组轴?
【发布时间】:2012-06-12 18:10:18
【问题描述】:

我在一个图中使用子图有几个图。每个轴实例用于引用一组特定的轴。像这样:

ax[0] = fig.add_subplot(2, 2, 1)
ax[1] = fig.add_subplot(2, 1, 2)
ax[2] = fig.add_subplot(2, 2, 2,projection='3d')

如您所见,我的一组坐标轴是 3d 图。我对其他图的属性之一进行了更改,如下所示:

plt.setp(zh, xdata=event.xdata,ydata=event.ydata)

然后像这样重新绘制:

zh.figure.canvas.draw();

但是,这是用所有 suplot 重新绘制整个图形,包括 3D 投影的图形,这大大减慢了速度。

我试过了:

ax[0].draw_artist(zh)

我认为这是有希望的,但轴没有更新。我没有收到错误,只是没有重新绘制。我也试过了:

zh.axes.draw(zh,ax[0])

但这给出了错误:

AttributeError: 'Line2D' object has no attribute 'open_group'

关于为什么会发生这种情况的任何想法,以及如何重新绘制我正在更改的轴实例而不是整个图形?

编辑:

zh 是 Line2D 对象:

zh, = plt.plot(z.real, z.imag, 'x', ms=10)

【问题讨论】:

  • Please be a bit more specific - 你用什么特定的库来绘制这个? Matplotlib、numpy、PyX 等?
  • setpLine2D 的使用将其标记为 Matplotlib,我会说。我添加了一个标签,如果猜测不正确,OP 可以更正。
  • Martijn 是对的,我正在使用 matplotlib。
  • 你能解释一下zh是什么吗?
  • zh 是一个 line2D 对象。见编辑。

标签: python matplotlib


【解决方案1】:

您不能绘制单个轴,但您只能更新单个轴。

基本上,您需要对事物进行 blit。如果轴的范围(以及刻度等)发生变化,这将变得更加复杂。目前,我认为情况并非如此。

作为一个过于简单的例子:

import matplotlib.pyplot as plt
import numpy as np

plt.ion()
x = np.linspace(0, 4*np.pi, 100)
fig, axes = plt.subplots(nrows=3)

fig.canvas.draw()
background = fig.canvas.copy_from_bbox(axes[0].bbox)

lines = [ax.plot(x, np.cos(x))[0] for ax in axes]
fig.canvas.draw()

for phase in range(1000):
    fig.canvas.restore_region(background)
    lines[0].set_ydata(np.cos(x + phase / 5.0))
    axes[0].draw_artist(lines[0])
    fig.canvas.blit(axes[0].bbox)

但是,新的matplotlib.animations 会为您处理此操作,并且只会对您指定的艺术家的轴进行 blit。

这是使用matplotlib.animations.FuncAnimation编写的相同示例:

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np

x = np.linspace(0, 4*np.pi, 100)
fig, axes = plt.subplots(nrows=3)

lines = [axes[0].plot(x, np.cos(x), animated=True)[0]]
lines += [ax.plot(x, np.cos(x)) for ax in axes[1:]]

class Update(object):
    def __init__(self, line):
        self.phase = 0
        self.line = line
    def __call__(self, _):
        self.line.set_ydata(np.cos(x + self.phase / 5.0))
        self.phase += 1.0
        return [self.line]

anim = FuncAnimation(fig, Update(lines[0]), interval=0, blit=True) 
plt.show()

哪些艺术家被动画化(以及哪些轴被更新)由函数(或可调用对象,如本例)返回的艺术家控制。

【讨论】:

  • 感谢这个全面的答案,你真的给了我一些很好的代码来咀嚼。我最终将 3d 绘图从图中移到了它自己的位置,只是为了简化事情(而且我的截止日期非常紧迫),但我非常热衷于使用上面的方法来完成这项工作。
  • 还有办法改变一个子图的背景颜色吗?
  • @JoeKington 您介意扩大答案以包括数据范围变化的情况吗?我相信它会帮助很多人。
猜你喜欢
  • 1970-01-01
  • 2021-12-08
  • 2016-10-09
  • 2019-07-15
  • 2018-08-15
  • 1970-01-01
  • 1970-01-01
  • 2022-08-21
  • 2016-09-24
相关资源
最近更新 更多