我正在创建一个仪表板来可视化数据。 在 Python 中使用 Plotly、dash 包
使用
prepare_plot_data and prepare_data_trend
函数准备绘图数据
在一张图中创建两个子图,使用
make_subplots
为子图设置图形布局,但两个子图重叠在同一位置
据我所知,make_subplots 可以用 row 和 col 定义子图的位置。在我的例子中,我定义行等于 2,列等于 1,这意味着图中将有两个位置,一个在 (1, 1) 另一个在 (2, 1)
当我绘制第一个热图时,我将行设置为 1,列设置为 1,我认为它会将图形放在 (1, 1) 位置,第二个我将行设置为 2,列设置为 1 ,它会把图形放在(2, 1),但结果和我想象的不一样
有谁知道如何将子图分成不同的位置?还是我误解了情节
make_subplots
?
from datetime import date, datetime
from functools import reduce
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from dash import Dash, Input, Output, dcc, html
from loguru import logger
from plotly.subplots import make_subplots
from scipy import stats
class OverView:
def __init__(self):
self.catologs = ["1","2","3",]
def prepare_plot_data(self, start_date, end_date):
data = [
{"date":"2020-01-01", "1":0.1},
{"date":"2020-01-01", "2":-0.1},
{"date":"2020-01-01", "3":0.9},
{"date":"2020-02-01", "1":0.1},
{"date":"2020-02-01", "2":0.1},
{"date":"2020-02-01", "3":0.1},
{"date":"2020-03-01", "1":0.1},
{"date":"2020-03-01", "2":0.1},
{"date":"2020-03-01", "3":0.1},
]
return pd.DataFrame(data)
def prepare_data_trend(self, start_date, end_date):
data = [
{"year-month":"2020-01", "id":"1", "normal_slope":0.1},
{"year-month":"2020-01", "id":"2", "normal_slope":-0.1},
{"year-month":"2020-01", "id":"3", "normal_slope":0.9},
{"year-month":"2020-02", "id":"1", "normal_slope":0.12},
{"year-month":"2020-02", "id":"2", "normal_slope":0.15},
{"year-month":"2020-02", "id":"3", "normal_slope":-0.15},
{"year-month":"2020-03", "id":"1", "normal_slope":0.5},
{"year-month":"2020-03", "id":"2", "normal_slope":0.3},
{"year-month":"2020-03", "id":"3", "normal_slope":0.2},
]
return pd.DataFrame(data)
def plot(self, start_date=None, end_date=None):
df = self.prepare_plot_data(start_date, end_date)
df_trend = self.prepare_data_trend(start_date, end_date)
fig = make_subplots(
rows=2, cols=1, row_heights=[0.6, 0.4],
specs=[
[{"type": "xy", "colspan": 1, "rowspan": 1}],
[{"type": "xy", "colspan": 1, "rowspan": 1, "secondary_y": True}],
],
horizontal_spacing=0,
vertical_spacing=0.01,
)
fig1 = go.Heatmap(
x=df_trend['year-month'].tolist(),
y=df_trend['id'].tolist(),
z=df_trend['normal_slope'].tolist(),
colorbar=dict(title='heat'),
)
fig.add_trace(fig1, row=1, col=1,)
fig.update_traces(colorbar_orientation='h', selector=dict(type='heatmap'))
for catolog in self.catologs:
fig.add_trace(
go.Scatter(
x=df["date"].values,
y=df[catolog].values,
name=catolog,
),
secondary_y=True,
row=2, col=1,
)
return fig
def run_dash(self):
app = Dash(__name__)
app.layout = html.Div(
[
html.H1("tmp Overview"),
dcc.DatePickerRange(
id="my-date-picker-range",
min_date_allowed=date(1990, 1, 1),
max_date_allowed=date(2100, 12, 31),
initial_visible_month=date(2021, 1, 1),
start_date=date(2018, 1, 1),
end_date=date(2023, 12, 31),
),
dcc.Graph(id="graph"),
],
)
@app.callback(
Output("graph", "figure"),
[
Input("my-date-picker-range", "start_date"),
Input("my-date-picker-range", "end_date"),
],
)
def update_output(start_date, end_date):
return self.plot(start_date, end_date)
app.run_server(debug=True)
OverView().run_dash()