我有一個 Dash 應用程式正在運行,它呼叫創建和保存圖表的函式。
該應用程式遇到由圖表繪制引起的超時。Matplotlib 列印警告:
Starting a Matplotlib GUI outside of the main thread will likely fail.
據我所知,Dash 應用程式由運行不同執行緒的 Flask 托管。這似乎是 matploblib 的一個問題,因為它不是執行緒保存。我使用threaded=False引數運行應用程式,但問題仍然存在。在除錯應用程式時,Flask 似乎仍在運行多個執行緒。
matplotlib
↓ 點擊按鈕,然后..

Generating & Downloading High-Throughput Quantities of Subplots in Dash (without any use of mpl.pyplot)
In this extended example of the previous code, I added a numeric input component (dcc.Input w/ type='number', max=1200, step=1; you can of course also just type any number 1 <= n <= 1200), so when you click the download button, the file you get is a pdf with potentially hundreds, or thousands, of plots having been generated.
import os
import random
from time import time_ns
import dash
import matplotlib
import matplotlib as mpl
matplotlib.use("agg")
import numpy as np
from dash import dcc
from dash import html
from dash.dependencies import Input
from dash.dependencies import Output
from dash.dependencies import State
from matplotlib.backends.backend_pdf import PdfPages
from matplotlib.figure import Figure
import seaborn as sns
sns.set(
font_scale=0.2
) # this erases labels for any blank plots on the last page
ctheme = [
"k", "gray", "magenta", "fuchsia", "#be03fd", "#1e488f",
(0.443_137_254_901_960_76, 0.443_137_254_901_960_76,
0.886_274_509_803_921_53, ), "#75bbfd", "teal", "lime", "g",
(0.666_667_4, 0.666_666_3, 0.290_780_141_843_971_38), "y",
"#f1da7a", "tan", "orange", "maroon", "r"
] # colors to blend to any scalar-spread palette form
def new_page(m, n):
fig = Figure()
axarr = fig.subplots(m, n, sharex="all", sharey="all")
arr_ij = [(x, y) for x, y in np.ndindex(m, n)]
subplots = [axarr[index] for index in arr_ij]
return (fig, subplots)
def generate_figures(n_plots, m=6, n=5):
fig_path = f"rand-poiss-hist_N={n_plots}_{time_ns()}.pdf"
colors = sns.blend_palette(ctheme, n_plots)
x = 0
with PdfPages(fig_path) as pdf:
for _ in range((n_plots // (m * n)) 1):
fig, subplots = new_page(m, n)
fig.subplots_adjust(wspace=0.5, hspace=0.5)
for i in range(m * n): # Random dist plots
ax = subplots[i]
x = 1
if x <= n_plots:
scaled_y = np.random.randint(20, 30)
random_data = np.random.poisson(scaled_y, 100)
ax.hist(
random_data,
bins=12,
fc=(0, 0, 0, 0),
lw=0.75,
ec=colors.pop(),
)
# Axes label properties
ax.set_title(f"fig.{x}", size=6)
if ax.is_last_row() or ((n_plots - x) <= n):
ax.set_xlabel("X Label", size=4)
if ax.is_first_col():
ax.set_ylabel("Y Label", size=4)
# ax.set_xmargin(2)
# ax.set_ymargin(2)
# NOTE:
# Save figure ~
# * BUT DO NOT USE PYLAB *
# Write figure to output file (png|pdf).
pdf.savefig(fig)
return fig_path
app = dash.Dash(__name__)
app.layout = html.Div(
[
html.Button(
"Generate plots",
id="generate-plot",
style={
"width": "30%",
"fontSize": "1.1rem",
},
),
html.Br(),
html.Code("Enter number of plots to generate:"),
html.Br(),
dcc.Input(id="range", type="number", min=1, max=1200, step=1),
dcc.Download(id="download-image"),
],
style={"margin": "10% 40% 10% 40%"}
)
@app.callback(
Output("download-image", "data"),
Input("generate-plot", "n_clicks"),
State("range", "value"),
prevent_initial_call=True,
)
def generate_downloadable_figure(n_clicks, n_plots):
if n_clicks > 0:
fig_path = generate_figures(n_plots)
return dcc.send_file(fig_path)
if __name__ == "__main__":
app.run_server(debug=True, dev_tools_hot_reload=True, host="0.0.0.0")

→ Clicking button downloads multiple (as applicable) page PDF of subplots
N=60 plots

N=231 plots
(Took about ten-twenty seconds..)

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/330145.html
標籤:Python matplotlib 烧瓶 线程安全 情节破折号
