我有以下数据:
import random
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import plotly.express as px
from plotly.subplots import make_subplots
from dash import Dash, html, dcc, Input, Output, dash_table, no_update
np.random.seed(0)
df = pd.DataFrame({'DATE_TIME': pd.date_range('2022-11-01', '2022-11-06 23:00:00', freq='20min'),
'ID': [random.randrange(1, 3) for n in range(430)]})
df['VALUE1'] = [random.uniform(110, 160) for n in range(430)]
df['VALUE2'] = [random.uniform(50, 80) for n in range(430)]
df['INSPECTION'] = df['DATE_TIME'].dt.day
df['MODE'] = np.select([df['INSPECTION'] == 1, df['INSPECTION'].isin([2, 3])], ['A', 'B'], 'C')
df['TIME'] = df['DATE_TIME'].dt.time
df['TIME'] = df['TIME'].astype('str')
df['TIMEINTERVAL'] = df.DATE_TIME.diff().astype('timedelta64[m]')
df['TIMEINTERVAL'] = df['TIMEINTERVAL'].fillna(0)
def to_day_period(s):
bins = ['0', '06:00:00', '13:00:00', '18:00:00', '23:00:00', '24:00:00']
labels = ['Nighttime', 'Daytime', 'Daytime', 'Nighttime', 'Nighttime']
return pd.cut(
pd.to_timedelta(s),
bins=list(map(pd.Timedelta, bins)),
labels=labels, right=False, ordered=False
)
df['TIME_OF_DAY'] = to_day_period(df['TIME'])
app = Dash(__name__)
app.layout = html.Div([
html.H4('Interactive Scatter Plot'),
html.Div('Size of dataset = ' + str(len(df)), id='size', style={'whiteSpace': 'pre-wrap'}),
html.P("Select ID:"),
dcc.Dropdown(df.ID.unique(), id='pandas-dropdown-1'), # for choosing ID,
html.P("Filter by time interval during nighttime (18:00-6:00):"),
dcc.RangeSlider(
id='range-slider-night',
min=0, max=600, step=10,
marks={0: '0', 50: '50', 100: '100', 150: '150', 200: '200', 250: '250', 300: '300', 350: '350', 400: '400',
450: '450', 500: '500', 550: '550', 600: '600'},
value=[0, 600]
),
html.P("Filter by time interval during daytime (6:00-18:00):"),
dcc.RangeSlider(
id='range-slider-morning',
min=0, max=600, step=10,
marks={0: '0', 50: '50', 100: '100', 150: '150', 200: '200', 250: '250', 300: '300', 350: '350', 400: '400',
450: '450', 500: '500', 550: '550', 600: '600'},
value=[0, 600]
),
dcc.Graph(id="scatter-plot", style={'width': '130vh', 'height': '80vh'}),
html.Div(id='dd-output-container')
])
@app.callback(
Output("scatter-plot", "figure"),
Output("size", "children"),
Input("pandas-dropdown-1", "value"),
Input("range-slider-night", "value"),
Input("range-slider-morning", "value"),
prevent_initial_call=True)
def update_lineplot(value, slider_range_night, slider_range_morning):
low_night, high_night = slider_range_night
low_morning, high_morning = slider_range_morning
df_night = df.query(
"(ID == @value) & (TIME_OF_DAY == 'Nighttime') & (TIMEINTERVAL >= @low_night) & (TIMEINTERVAL < @high_night)").copy()
df_morning = df.query(
"(ID == @value) & (TIME_OF_DAY == 'Daytime') & (TIMEINTERVAL >= @low_morning) & (TIMEINTERVAL < @high_morning)").copy()
df1 = pd.concat([df_night, df_morning], axis=0).sort_values(['DATE_TIME'])
text = f"The size of dataset = {len(df)} \n Selected points = {len(df1)}, unselected points = {len(df) - len(df1)}, \n df_night = {len(df_night)}, df_morning = {len(df_morning)}"
if df1.shape[0] != 0:
fig = px.line(df1, x="DATE_TIME", y=["VALUE1", "VALUE2"],
facet_col='INSPECTION',
facet_col_wrap=2,
symbol='MODE', hover_data=['TIMEINTERVAL'],
facet_row_spacing=0.1,
facet_col_spacing=0.09)
fig.update_xaxes(matches=None, showticklabels=True)
return fig, text
else:
return no_update
app.run_server(debug=True, use_reloader=False)
此代码根据每个 ID 的检查次数生成多个图。它根据检查次数为每个 ID 显示多个图。
我尝试使用 matplotlib 解决方案,但它们很旧并且不适用于我的实现。
我期望的是: 我不想一次看到所有地块,而是想用箭头导航每个检查地块。
我想要的: