Tcl错误:在Python 2.7中使用Flask和Matplotlib超出堆栈空间

时间:2015-12-08 15:28:45

标签: python-2.7 matplotlib flask tkinter

感谢您的时间:

我创建了一个烧瓶服务器,它从表单帖子中获取变量并输出饼图或条形图。在调试时,我注意到了这个错误:

Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "C:\Python27\lib\atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "C:\Python27\lib\site-packages\matplotlib\_pylab_helpers.py", line 92, in destroy_all
    manager.destroy()
  File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 618, in destroy
    self.canvas._tkcanvas.after_cancel(self.canvas._idle_callback)
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 616, in after_cancel
    self.tk.call('after', 'cancel', id)
TclError: out of stack space (infinite loop?)
Error in sys.exitfunc:
Traceback (most recent call last):
  File "C:\Python27\lib\atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "C:\Python27\lib\site-packages\matplotlib\_pylab_helpers.py", line 92, in destroy_all
    manager.destroy()
  File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 618, in destroy
    self.canvas._tkcanvas.after_cancel(self.canvas._idle_callback)
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 616, in after_cancel
    self.tk.call('after', 'cancel', id)
_tkinter.TclError: out of stack space (infinite loop?)

这似乎导致服务器重新加载(成功地为它的价值)这是一个问题。不知道在这里发生了什么,除了tkinter感到不安。而且,我的google fu没有运气。

烧瓶服务器(w调试设置。映射的变量是由项目需求决定的。):

# Flask App that functions as a graph end point replacement "DAC-780"
# Standard Library
import os
import uuid
# Third Party
from flask import Flask, request
# Local
from pie import make_pie
from bar import make_bar


app_root = os.path.dirname(os.path.abspath(__file__))
images = os.path.join(app_root, 'static/images')
app = Flask(__name__, static_folder="static")
app._static_folder = os.path.join(app_root, 'static')

@app.route('/charts/<path>', methods=['POST'])
def graph(path):

    g_data_list = []
    file_name = str(uuid.uuid4())
    # if bar graph
    if path == "chart4.asp":
        # grab vars
        g_title = str(request.form['Title'])
        x_title = str(request.form['CatTitle'])
        y_title = str(request.form['ValTitle'])
        ser1 = str(request.form['Ser1'])
        ser2 = str(request.form['Ser2'])
        cat1 = str(request.form['Cat1'])
        cat2 = str(request.form['Cat2'])
        cat3 = str(request.form['Cat3'])
        cat4 = str(request.form['Cat4'])
        cat5 = str(request.form['Cat5'])
        cat6 = str(request.form['Cat6'])
        cat7 = str(request.form['Cat7'])
        cat8 = str(request.form['Cat8'])
        cat9 = str(request.form['Cat9'])
        cat10 = str(request.form['Cat10'])
        cat11 = str(request.form['Cat11'])
        cat12 = str(request.form['Cat12'])
        cat13 = str(request.form['Cat13'])
        s1d1 = int(request.form['S1D1'])
        s1d2 = int(request.form['S1D2'])
        s1d3 = int(request.form['S1D3'])
        s1d4 = int(request.form['S1D4'])
        s1d5 = int(request.form['S1D5'])
        s1d6 = int(request.form['S1D6'])
        s1d7 = int(request.form['S1D7'])
        s1d8 = int(request.form['S1D8'])
        s1d9 = int(request.form['S1D9'])
        s1d10 = int(request.form['S1D10'])
        s1d11 = int(request.form['S1D11'])
        s1d12 = int(request.form['S1D12'])
        s1d13 = int(request.form['S1D13'])
        s2d1 = int(request.form['S2D1'])
        s2d2 = int(request.form['S2D2'])
        s2d3 = int(request.form['S2D3'])
        s2d4 = int(request.form['S2D4'])
        s2d5 = int(request.form['S2D5'])
        s2d6 = int(request.form['S2D6'])
        s2d7 = int(request.form['S2D7'])
        s2d8 = int(request.form['S2D8'])
        s2d9 = int(request.form['S2D9'])
        s2d10 = int(request.form['S2D10'])
        s2d11 = int(request.form['S2D11'])
        s2d12 = int(request.form['S2D12'])
        s2d13 = int(request.form['S2D13'])

        # vars i mapped but weren't needed for my graph lib
        g_type = str(request.form['Type'])
        g_cats = str(request.form['Cats'])
        g_series = str(request.form['Series'])
        cat_title = str(request.form['CatTitle'])

        # add data to g_data_list so we can process it
        g_data_list.append((ser1, [s1d1, s1d2, s1d3, s1d4, s1d5, s1d6, s1d7, s1d8,
                                s1d9, s1d10, s1d11, s1d12, s1d13]))
        g_data_list.append((ser2, [s2d1, s2d2, s2d3, s2d4, s2d5, s2d6, s2d7, s2d8,
                                s2d9, s2d10, s2d11, s2d12, s2d13]))
        x_labels = [cat1, cat2, cat3, cat4, cat5, cat6, cat7, cat8, cat9, cat10,
                    cat11, cat12, cat13]
        # make a graph to return in html
        graph = make_bar(g_title, y_title, x_labels, g_data_list, file_name, cat_title, x_title)

    else:
        # all others are probably pie graphs
        g_title = str(request.form['Title'])
        cat1 = str(request.form['Cat1'])
        cat2 = str(request.form['Cat2'])
        cat3 = str(request.form['Cat3'])
        cat4 = str(request.form['Cat4'])
        s1d1 = int(request.form['S1D1'])
        s1d2 = int(request.form['S1D2'])
        s1d3 = int(request.form['S1D3'])
        s1d4 = int(request.form['S1D4'])
        # vars that aren't needed for replications of the final product, but
        # were part of the old code
        g_type = str(request.form['Type'])
        g_cats = str(request.form['Cats'])
        g_series = str(request.form['Series'])
        cat_title = str(request.form['CatTitle'])
        val_title = str(request.form['ValTitle'])
        s1 = str(request.form['Ser1'])
        s2 = str(request.form['Ser2'])
        # add data
        g_data_list.append([cat1, s1d1])
        g_data_list.append([cat2, s1d2])
        g_data_list.append([cat3, s1d3])
        g_data_list.append([cat4, s1d4])
        # make graph to send back via html
        graph = make_pie(g_title, g_data_list, file_name)
    # make a web page with graph and return it
    html = """
        <html>
             <head>
                  <title>%s</title>
             </head>
              <body>
                 <img src="/static/images/%s.png" alt="An Error Occured"/>

             </body>
        </html>
        """ % (g_title, str(file_name))


    return html

if __name__ == '__main__':
    app.run(port=3456, host="0.0.0.0", debug=True)

bar.py:

# creates a bar chart based on input using matplotlib
import os
import numpy as np
import matplotlib.pyplot as plt
from pylab import rcParams
rcParams['figure.figsize'] = 6.55, 3.8
app_root = os.path.dirname(os.path.abspath(__file__))
images = os.path.join(app_root, 'static/images')

def make_bar(g_title, y_title, x_labels, data_series, file_name, cat_title,
             x_title):

    n_groups = 13
    bar_width = 0.35
    opacity = 0.4
    fig, ax = plt.subplots()
    index = np.arange(n_groups)
    error_config = {'ecolor': '0.3'}
    plt.bar(index, tuple(data_series[0][1]), bar_width,
                     alpha=opacity,
                     color='b',
                     error_kw=error_config,
                     label='{}'.format(data_series[0][0]))

    plt.bar(index + bar_width, tuple(data_series[1][1]), bar_width,
                     alpha=opacity,
                     color='r',
                     error_kw=error_config,
                     label='{}'.format(data_series[1][0]))

    box = ax.get_position()
    ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])
    plt.xlabel(x_title, fontsize=10)
    plt.ylabel(y_title, fontsize=10)
    plt.title(g_title, fontsize=11)
    plt.xticks(index + bar_width, tuple(x_labels), fontsize=8)
    plt.yticks(fontsize=8)
    plt.axis('tight')
    lgd = plt.legend(fontsize=8, bbox_to_anchor=(1.15, 0.5))
    plt.tight_layout()
    plt.draw()
    plt.savefig('{}/{}.png'.format(images, file_name),
                dpi=100, format='png', bbox_extra_artists=(lgd,),
                bbox_inches='tight')

    return

pie.py:

# creates a pie chart w/ matplotlib

import os

import matplotlib.pyplot as plt
from pylab import rcParams

app_root = os.path.dirname(os.path.abspath(__file__))
images = os.path.join(app_root, 'static/images')

def make_pie(title, g_data_list, file_name):
    rcParams['figure.figsize'] = 5.75, 3
    labels = [entry[0] for entry in g_data_list]
    sizes = [entry[1] for entry in g_data_list]
    ax = plt.subplot(111)
    box = ax.get_position()
    ax.set_position([box.x0, box.y0, box.width * 0.7, box.height])
    patches, texts = ax.pie(sizes, startangle=90)
    ax.legend(patches, labels, loc='center left',
              bbox_to_anchor=(.9, 0.5), fontsize=8)
    plt.axis('equal')
    plt.suptitle(g_title, fontsize=12)
    plt.draw()
    plt.savefig('{}/{}.png'.format(images, file_name), dpi=100, format='png')

    return

2 个答案:

答案 0 :(得分:0)

我注意到,在关闭绘图窗口后,绘制所有内容的函数(单独运行时)将保持运行状态。添加plt.clf()修复了这个问题,并且似乎也是我与Flask相关的解决方案。

答案 1 :(得分:0)

seaborn也有同样的问题

import matplotlib
matplotlib.use('Agg')

对我有帮助。

详细信息:https://matplotlib.org/faq/usage_faq.html#what-is-a-backend