如何在Dash中显示matplotlib子图?

w3nuxt5m  于 2023-05-18  发布在  其他
关注(0)|答案(1)|浏览(140)

我知道如何使用以下脚本在Dash中显示单个matplotlib图:

import dash
import dash_core_components as dcc
import dash_html_components as html
import numpy as np
import matplotlib.pyplot as plt

app = dash.Dash()

app.layout = html.Div(children=[
    html.H1(children='Hello Dash'),

    dcc.Slider(
        id='n_points',
        min=10,
        max=100,
        step=1,
        value=50,
    ),

    dcc.Graph(id='example') # or something other than Graph?...
])

@app.callback(
    dash.dependencies.Output('example', 'figure'),
    [dash.dependencies.Input('n_points', 'value')]
)

def update_figure(n_points):
    #create some matplotlib graph
    x = np.random.rand(n_points)
    y = np.random.rand(n_points)
    a = plt.scatter(x, y)
    # plt.show()
    return a

if __name__ == '__main__':
    app.run_server(debug=True)

我遇到的问题是,我不知道如何用破折号显示单个/多个matplotlib径向图,因为我有多个ax.plot和ax.fill_between调用。我使用以下代码创建合成数据并通过matplotlib绘制。

import numpy as np
import pandas as pd
import random
import matplotlib.pyplot as plt

# create the dummy data
hour_timetable = [i for i in range(24)]
df = pd.DataFrame({'DATE_TIME': pd.date_range('2022-11-01', '2022-11-01 23:59:00', freq='20min'),
                   'ID': [random.randrange(1, 2) for n in range(72)]})
df['HOUR'] = df['DATE_TIME'].dt.hour
df['MINUTE'] = df['DATE_TIME'].dt.minute
df['DBP'] = np.random.uniform(50, 80, size=72)
df['DBP2'] = np.random.uniform(45, 75, size=72)
df['SBP'] = np.random.uniform(110, 180, size=72)
df['SBP2'] = np.random.uniform(90, 130, size=72)
df['TIME'] = df['DATE_TIME'].dt.time
df = df[(df.ID==1)]

df['DATE_TIME'] = pd.to_datetime(df['DATE_TIME'])
df['seconds'] = df['DATE_TIME'].dt.hour*60+df['DATE_TIME'].dt.minute

# Compute areas and colors
hour_minute = np.linspace(0, 2*np.pi, 24*60, endpoint=False)

# print(len(hour_minute))
r = df.SBP.tolist()
r2 = df.SBP2.tolist()
s = df.DBP.tolist()
s2 = df.DBP2.tolist()
theta = df.SBP # power = SBP
area = r
colors = r

fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})

ax.plot(hour_minute[df['seconds']], r, color='red', label='SBP') # markers are controlled with 'o-'
ax.plot(hour_minute[df['seconds']], r2, color='red', label='SBP2')

ax.plot(hour_minute[df['seconds']], s, color='blue', label='DBP') # markers are controlled with 'o-'
ax.plot(hour_minute[df['seconds']], s2, color='blue', label='DBP2')

ax.fill_between(hour_minute[df['seconds']], r, r2, interpolate=True, color='red', alpha=0.3)
ax.fill_between(hour_minute[df['seconds']], s, s2, interpolate=True, color='blue', alpha=0.3)

# clock labels
ax.set_xticks(np.linspace(0, 2*np.pi, 24, endpoint=False))
ax.set_xticklabels(range(24))
ax.legend(loc='best', bbox_to_anchor=(1.0, 1.1), fontsize=8)

# make the labels go clockwise
ax.set_theta_direction(-1)
ax.set_ylim(0, 180)

# place 0 at the top
ax.set_theta_offset(np.pi/2.0)

plt.show()

如何在Dash中显示第二个脚本(在Matplotlib中创建的径向图)?感谢任何提示/答案。

w6lpcovy

w6lpcovy1#

显然,我应该创建多个Matplotlib图形并将它们编码为base64字符串。然后它就像一个魅力!下面是工作代码:

import dash
import dash_core_components as dcc
import dash_html_components as html
import numpy as np
import pandas as pd
import random
import matplotlib.pyplot as plt
from io import BytesIO
import base64

app = dash.Dash()

# create the dummy data
hour_timetable = [i for i in range(24)]
df = pd.DataFrame({'DATE_TIME': pd.date_range('2022-11-01', '2022-11-01 23:59:00', freq='20min'),
                   'ID': [random.randrange(1, 2) for n in range(72)]})
df['HOUR'] = df['DATE_TIME'].dt.hour
df['MINUTE'] = df['DATE_TIME'].dt.minute

# Compute areas and colors
hour_minute = np.linspace(0, 2 * np.pi, 24 * 60, endpoint=False)

charts = []
for i in range(5):
    df['DBP'] = np.random.uniform(50, 80, size=72)
    df['DBP2'] = np.random.uniform(45, 75, size=72)
    df['SBP'] = np.random.uniform(110, 180, size=72)
    df['SBP2'] = np.random.uniform(90, 130, size=72)
    df['TIME'] = df['DATE_TIME'].dt.time
    df = df[(df.ID == 1)]

    df['DATE_TIME'] = pd.to_datetime(df['DATE_TIME'])
    df['seconds'] = df['DATE_TIME'].dt.hour * 60 + df['DATE_TIME'].dt.minute

    r = df.SBP.tolist()
    r2 = df.SBP2.tolist()
    s = df.DBP.tolist()
    s2 = df.DBP2.tolist()

    fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})

    ax.plot(hour_minute[df['seconds']], r, color='red', label='SBP')
    ax.plot(hour_minute[df['seconds']], r2, color='red', label='SBP2')
    ax.plot(hour_minute[df['seconds']], s, color='blue', label='DBP')
    ax.plot(hour_minute[df['seconds']], s2, color='blue', label='DBP2')
    ax.fill_between(hour_minute[df['seconds']], r, r2, interpolate=True, color='red', alpha=0.3)
    ax.fill_between(hour_minute[df['seconds']], s, s2, interpolate=True, color='blue', alpha=0.3)
    ax.set_xticks(np.linspace(0, 2 * np.pi, 24, endpoint=False))
    ax.set_xticklabels(range(24))
    ax.legend(loc='best', bbox_to_anchor=(1.0, 1.1), fontsize=8)
    ax.set_theta_direction(-1)
    ax.set_ylim(0, 180)
    ax.set_theta_offset(np.pi / 2.0)

    buffer = BytesIO()
    fig.savefig(buffer, format='png')
    buffer.seek(0)

    image_string = base64.b64encode(buffer.getvalue()).decode()

    charts.append(html.Div([
        html.H3(f'Radial Chart {i+1}'),
        html.Img(src='data:image/png;base64,' + image_string)
    ]))

app.layout = html.Div(children=[
    html.H1(children='Radial Charts'),
    dcc.Markdown('''
### Radial Charts
'''),
    *charts

])

if __name__ == '__main__':
    app.run_server(debug=True)

相关问题