11

以前,我遇到了多个 Matplotlib 图形之间的干扰问题。最后,我发现了一个问题,即某些 pyplot 函数不附加到它们的图形实例,但可以在并行创建的其他一些图形实例中呈现。

这是一些示例代码:

from django.http import HttpResponse
from numpy import arange, meshgrid
from matplotlib.mlab import bivariate_normal

def show_chart(request):
    delta = 0.025
    x = arange(-3.0, 3.0, delta)
    y = arange(-2.0, 2.0, delta)
    X, Y = meshgrid(x, y)
    Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
    Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
    Z = 10.0 * (Z2 - Z1)

    from matplotlib.pyplot import figure, contour
    fig1 = figure(figsize=(4, 4), facecolor='white')
    contour(X, Y, Z)

    response = HttpResponse(content_type='image/png')
    fig1.savefig(response, format='png')
    fig1.clear()
    return response

上面示例中的轮廓 pyplot 函数可以在 fig1 中呈现,但有时也可以在其他并行生成的图中呈现。这很烦人。有什么方法可以将轮廓 pyplot 函数附加到 fig1?

4

2 回答 2

21

作为对这里发生的事情的一点解释,matplotlib有两个半独立的接口;状态机和OO接口。

状态机代码设计用于在交互式外壳中工作(并模仿 matlab 的界面)。它通过将 OO 接口包装在一组命令中来实现这一点,这些命令跟踪当前figureaxes是什么。当您使用来自matplotlib.pyplot(我怀疑您from matploblib.pyplot import *的代码中有一个)的命令时, in 或多或少等同于做gcf().gca().contour(...). 当您创建一个新图形时,它会自动成为当前图形(如果您在迭代 shell 中使用它,这就是您想要的),因此您看到的行为是“正确的”行为。状态机界面也有代码,以确保在需要时重新绘制图形,管理 gui 事件循环等(您需要做的所有事情才能使交互界面顺利运行)。正如海登在评论中提到的那样,跑步ipython --pylab将自动运行from matplotlib.pyplot import *,这为您提供了一个非常好的交互式 shell。

OO 接口设计用于以编程方式处理matplotlib. 它增加了冗长的内容(您现在必须完成状态机的大部分工作),它弥补了清晰度。在 OO 模型中,大多数(可能是全部)绘图函数与Axes对象(doc)相关联(因为可以有多个轴与图形相关联(例如使用的子图gridspec)。

解决问题的另一种方法是

ax = fig1.gca()

这将从 中获取当前轴fig1,如有必要,创建一个。如果您跟踪您的图形对象,而不是您的轴对象并且想要向图形添加另一个图形,这可能会有所帮助。

于 2013-01-10T15:46:17.350 回答
12

您可以创建一个子图,然后调用子图的contour方法:

fig1 = figure(figsize=(4, 4), facecolor='white')
ax = fig1.add_subplot(111)
ax.contour(X, Y, Z)

plt.subplots只需一次调用即可方便地创建图形和子图:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
于 2013-01-10T09:43:30.787 回答