当前位置: 首页 > 面试题库 >

Matplotlib无法在Django上渲染多个轮廓图

尉迟韬
2023-03-14
问题内容

每当(至少)两个人尝试在我的应用程序中生成轮廓图时,其中至少一个会收到随机错误,具体取决于第一个人设法绘制的距离。(“未知元素o”,“
ContourSet必须为在当前的轴中”只是两种可能性)

以下是可能会产生错误的缩减测试,如果您尝试一次在2个或多个选项卡中加载此页面,则第一个将正确呈现,而第二个将产生错误。(我发现执行此操作的最简单方法是用鼠标中键几次单击chrome中的刷新页面按钮)

views.py

def home(request):
    return render(request, 'home.html', {'chart': _test_chart()})


def _test_chart():
    import base64
    import cStringIO
    import matplotlib
    matplotlib.use('agg')
    from matplotlib.mlab import bivariate_normal
    import matplotlib.pyplot as plt
    import numpy as np
    from numpy.core.multiarray import arange

    delta = 0.5

    x = arange(-3.0, 4.001, delta)
    y = arange(-4.0, 3.001, delta)
    X, Y = np.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 = (Z1 - Z2) * 10

    fig = plt.figure(figsize=(10, 5))
    plt.contour(X, Y, Z, 10, colors='k')

    jpg_image_buffer = cStringIO.StringIO()
    fig.savefig(jpg_image_buffer)

    array = base64.b64encode(jpg_image_buffer.getvalue())
    jpg_image_buffer.close()
    return array

home.html(仅这一行就足够了)

<img src="data:image/png;base64,{{ chart }}" />

我尝试使用mpld3代替它来处理图像的生成,但是这仍然会产生不同的错误,因此我知道它绝对不是保存图形,而是更多地生成图形。我也尝试过使用aThreadPoolThreading无济于事,据我所知,似乎在matplotlib中创建等高线图无法支持多个实例,这些实例将永远无法用于网站…

我现在能想到的唯一清晰的解决方案是,用其他我真的不想做的东西替换matplotlib。

有没有一种方法可以使用matplotlib生成对我有用的轮廓图?


问题答案:

首先,让我开始说,通过调用_test_chart几个线程可以更轻松地重现

from threading import Thread
for i in xrange(2):
    Thread(target=_test_chart).start()

执行上述操作后,一个将按预期工作,而第二个将崩溃。

这样做的简单原因是pyplot模块不是为多线程设计的,因此,两个图表在尝试绘制时会混淆它们的数据。

可以用mdboom更好地解释


pyplot用于在命令行方便地进行绘制,并保持全局状态。例如,当您说plt.figure()时,它会将图形添加到全局列表中,然后将“当前图形”指针设置为最近创建的图形。然后,随后的绘图命令将自动写入该图形。显然,这不是线程安全的…

有两种方法可以解决此问题,

  1. 强制在不同的过程中绘制这些图表。

    for i in xrange(2):
    pool = Pool(processes=1)
    pool.apply(_test_chart)

尽管这将起作用,但是您会发现性能显着下降,因为创建流程和生成图表所花的时间通常一样长(我认为这是不可接受的!)

  1. 真正的解决方案是使用Matplotlib的OO接口模块,该模块然后将允许您使用正确的对象-本质上,这适用于处理子图而不是图。对于问题中的给定示例,这类似于以下内容

    def _test_chart2():

    delta = 0.5
    
    x = arange(-3.0, 4.001, delta)
    y = arange(-4.0, 3.001, delta)
    X, Y = np.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 = (Z1 - Z2) * 10
    
    fig = figure(figsize=(10, 5))
    
    ax1 = fig.add_subplot(111)
    extents = [x.min(), x.max(), y.min(), y.max()]
    im = ax1.imshow(Z,
                    interpolation='spline36',
                    extent=extents,
                    origin='lower',
                    aspect='auto',
                    cmap=cm.jet)
    ax1.contour(X, Y, Z, 10, colors='k')
    
    jpg_image_buffer = cStringIO.StringIO()
    fig.savefig(jpg_image_buffer)
    
    array = base64.b64encode(jpg_image_buffer.getvalue())
    jpg_image_buffer.close()
    
    return array
    


 类似资料:
  • 问题内容: 我最近将笔记本电脑升级到Snow Leopard,将TeX升级到了3.1415926版本(TeX Live 2011 / MacPorts 2011_5),并安装了Python 2.7.3。完成所有这些安装后,我运行了macport selfupdate和macport升级过时的情况。但是,现在,当我尝试在matplotlib中使用TeX时,会收到以下信息: 类似于上一个问题,我尝试通

  • 问题内容: 我正在阅读面向Python开发人员的Matplotlib书,但正在努力遵循第8章“ Django应用程序中的Matplotlib”部分中的示例。 到目前为止,我已经发出了命令 然后在目录中 按照示例,我做了如下: 接下来,这本书说应当在其中添加以下行: 但是,我看不到它如何工作,因为在’default’中,有很多对象: 并且没有定义构造函数。也许这本书(来自2009年)指的是旧版Dja

  • 问题内容: 我想从均匀分布的2D数据(类似图像的数据)的单个轮廓中获取数据。 基于在类似问题中找到的示例:如何获得轮廓图(matplotlib)绘制的线的(x,y)值? 该调用的结果是: 基于这些图,此结果是有意义的,并且似乎是轮廓线的(y,x)对的集合。 除了手动遍历此返回值,提取直线的坐标并组装线的数组以外,还有更好的方法从对象取回数据吗?从中提取数据时是否有陷阱要注意? 或者,是否有其他选择

  • 问题内容: 如何将 嵌入边框 应用于HTML元素,但仅在其一侧。到现在为止,我一直在使用图像(GIF / PNG)执行此操作,然后将其用作背景并拉伸它(repeat-x),并从块的顶部移开一点。最近,我发现了 轮廓 CSS属性,这是伟大的!但是似乎将整个块都圈了起来…是否可以仅使用此边框属性在一个边界上执行此操作?另外,如果没有,您是否有任何CSS技巧可以代替背景图片?(以便稍后可以使用CSS等来

  • 问题内容: 我正在尝试使用以下格式的文件的matplotlib绘制轮廓图: x1 y1 z1 x2 y2 z2 等等 我可以用numpy.loadtxt加载它以获得向量。到目前为止,没有问题。 我阅读了这篇文章以了解如何进行绘制,并且可以通过复制粘贴来复制它,因此,我确定我的安装没有错: http://matplotlib.org/examples/pylab_examples/griddata_

  • 目标 在本章中,我们将学习 凸性缺陷以及如何找到它们 查找点到多边形的最短距离 匹配不同的形状 理论和代码 1. 凸性缺陷 我们看到了关于轮廓的第二章的凸包。从这个凸包上的任何偏差都可以被认为是凸性缺陷。 OpenCV有一个函数来找到这个,cv.convexityDefects()。一个基本的函数调用如下: hull = cv.convexHull(cnt,returnPoints = False