python - pyplot 在 macOS 中的 plt.figure() 上崩溃

标签 python django macos matplotlib tcl

当我调用 plt.figure() 时,我反复收到 RuntimeError: main thread is not in mainloop。

这是一个图表函数,它根据 django web 应用程序中的用户数据创建图表。

我在 python 3.4 中的 IDLE 上看到一条警告,称我的 Tcl/Tk 版本可能不稳定,链接到 http://www.python.org/download/mac/tcltk/有关更多信息,但这没有提供任何有关如何确定我在 venv 中运行的版本或如何更新 venv 中的版本的指导。

此错误仅发生在我的 macOS 环境中。

不确定我是否使用了 matplotlib 错误,或者是否需要更新我的环境。如果我需要更新,我不知道如何在虚拟环境中进行更新。

代码:

def visualize(frictionloss):
    """
    Input: an instance of a FrictionLoss model,
    Return: a bar chart of the losses in b64 encoded image
    """
    # 6 bars
    ind = np.arange(6)
    width = .65

    # load psi lost in each section to a bar to show
    losses1 = (frictionloss.ug_1_loss,
              frictionloss.ug_2_loss,
              frictionloss.riser_loss,
              frictionloss.bulk_main_loss,
              frictionloss.cross_main_loss,
              frictionloss.head_1_loss)

    # additionally, show each head loss to later stack on top
    losses2 = (0, 0, 0, 0, 0, frictionloss.head_2_loss)
    losses3 = (0, 0, 0, 0, 0, frictionloss.head_3_loss)
    losses4 = (0, 0, 0, 0, 0, frictionloss.head_4_loss)
    losses5 = (0, 0, 0, 0, 0, frictionloss.head_5_loss)
    losses6 = (0, 0, 0, 0, 0, frictionloss.head_6_loss)

    # backend here has to be forced to one thread, otherwise it misbehaves
    lock = Lock()
    lock.acquire()
    frictionFig = plt.figure()
    lock.release()

    # build a stack of bar charts on top of each other,
    # the first 5 bars only get used in chart 1,
    # the last bar gets used in all 6 to show each head in the branch line
    ax = frictionFig.add_subplot(111)
    rects1 = ax.bar(ind, losses1, width, color='#e05757')
    rects2 = ax.bar(ind, losses2, width, color='#a38080', bottom=losses1)
    rects3 = ax.bar(ind, losses3, width, color='#efcece', bottom=losses2)
    rects4 = ax.bar(ind, losses4, width, color='#d69393', bottom=losses3)
    rects5 = ax.bar(ind, losses5, width, color='#fc6767', bottom=losses4)
    rects6 = ax.bar(ind, losses6, width, color='#a38080', bottom=losses5)

    # set axes and labels
    ax.set_ylabel('Lost Pressure (psi)')
    ax.set_xticklabels(('',
                       'UG 1',
                       'UG 2',
                       'Riser',
                       'Bulk Main',
                       'Cross Main',
                       'Heads'))

    # remove the frame lines
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.spines['left'].set_visible(False)
    ax.spines['bottom'].set_visible(False)

    # Converts the graph into a string to be sent as a context variable
    buffer = BytesIO()
    frictionFig.savefig(buffer, format='png')
    buffer.seek(0)
    graph = quote(b64encode(buffer.getvalue()))

    return graph

错误:

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/densitycurve/

Django Version: 1.11
Python Version: 3.6.1
Installed Applications:
['django.contrib.admin',
 'django.contrib.sites',
 'registration',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'home',
 'hydrograph',
 'densitycurve',
 'storage',
 'frictionloss',
 'flowtest',
 'pipeweight',
 'result',
 'useraccount',
 'watersupply',
 'seismichanger',
 'widget_tweaks',
 'crispy_forms']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/Users/Mark/Desktop/Professional/FSC/water/WATER/ENV/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/Users/Mark/Desktop/Professional/FSC/water/WATER/ENV/lib/python3.6/site-packages/django/core/handlers/base.py" in _legacy_get_response
  249.             response = self._get_response(request)

File "/Users/Mark/Desktop/Professional/FSC/water/WATER/ENV/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/Users/Mark/Desktop/Professional/FSC/water/WATER/ENV/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/Users/Mark/Desktop/Professional/FSC/water/WATER/ENV/lib/python3.6/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  23.                 return view_func(request, *args, **kwargs)

File "/Users/Mark/Desktop/Professional/FSC/water/WATER/densitycurve/views.py" in densitycurve
  160.          (graph, outputText) = processData(densityInstance, request)

File "/Users/Mark/Desktop/Professional/FSC/water/WATER/densitycurve/views.py" in processData
  204.  densityFigure = plt.figure()

File "/Users/Mark/Desktop/Professional/FSC/water/WATER/ENV/lib/python3.6/site-packages/matplotlib/pyplot.py" in figure
  535.                                         **kwargs)

File "/Users/Mark/Desktop/Professional/FSC/water/WATER/ENV/lib/python3.6/site-packages/matplotlib/backends/backend_tkagg.py" in new_figure_manager
  81.     return new_figure_manager_given_figure(num, figure)

File "/Users/Mark/Desktop/Professional/FSC/water/WATER/ENV/lib/python3.6/site-packages/matplotlib/backends/backend_tkagg.py" in new_figure_manager_given_figure
  98.         icon_img = Tk.PhotoImage(file=icon_fname)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/__init__.py" in __init__
  3539.         Image.__init__(self, 'photo', name, cnf, master, **kw)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/__init__.py" in __init__
  3495.         self.tk.call(('image', 'create', imgtype, name,) + options)

Exception Type: RuntimeError at /densitycurve/
Exception Value: main thread is not in main loop

最佳答案

更新:

可以通过使用非交互式后端 ( reference ) 来解决此问题。我没有发现这个答案,因为更改 django 中的后端有点棘手。

标准方法是在模块顶部编写:

模型.py:

import matplotlib  
matplotlib.use('Agg')  
from matplotlib import pyplot as plt  

然而在django中,matplotlib可能会在你的模块导入之前被导入,并且后端只能下注一次!因此,要可靠地更改后端,您必须在 django 设置文件中导入 matplotlib:

设置.py:

import matplotlib
matplotlib.use('Agg')

关于python - pyplot 在 macOS 中的 plt.figure() 上崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44030430/

相关文章:

macos - 定位命令在 Mac 上的文档文件夹中找不到任何内容

objective-c - 核心情节 mouseMoved

python - 开源 Enthought Python 替代方案

python - 如何在 Django 管理更改表单中显示相关表的内容?

python - Django 按属性字段排序

python - Bootstrap 未设置为 Django 应用程序

macos - Git 别名参数完成在 Zsh 中不起作用

python - 使用 Python 的 replace() 方法实现停用词功能

python - 列表索引超出范围 - Python 索引错误

Python "denormalize"unicode 组合字符