У меня есть точечная диаграмма с несколькими следами. Я хотел бы иметь возможность сдвигать одну трассу вперед и назад во времени, в то время как остальные остаются фиксированными.
Я могу добиться этого, создав несколько трасс с предустановленными смещениями, но это приводит к огромным файлам (18 МБ против 4 Мб без всех шагов). Можно ли обновить данные трассировки с помощью ползунка?
график без ползунка:
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
data = "https://gist.githubusercontent.com/simonmcconnell/42654e09f17805f63b2afa2cdc7166c1/raw/5dbed5a14bc6db6912420d5a1ae4e82e173f6a34/sampledata.csv"
col_names = [
"DATE",
"TIME",
"A",
"B",
"C",
]
dtypes = {
"A": "float64",
"B": "float64",
"C": "float64",
}
df = pd.read_csv(
data,
header=0,
names=col_names,
dtype=dtypes,
parse_dates=[["DATE", "TIME"]],
infer_datetime_format=True,
dayfirst=True,
cache_dates=True,
skipinitialspace=True,
)
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(
go.Scatter(
x=df["DATE_TIME"],
y=df["B"],
mode="lines",
name="B",
),
secondary_y=False,
)
fig.add_trace(
go.Scatter(
x=df["DATE_TIME"],
y=df["C"],
mode="lines",
),
secondary_y=False,
)
fig.add_trace(
go.Scatter(
x=df["DATE_TIME"],
y=df["A"],
mode="lines",
),
secondary_y=True,
)
fig.write_html("no_offset.html", auto_open=True)
график с ползунком:
from datetime import timedelta
import pandas as pd
import numpy as np
import humanize
import plotly.graph_objects as go
from plotly.subplots import make_subplots
data = "https://gist.githubusercontent.com/simonmcconnell/42654e09f17805f63b2afa2cdc7166c1/raw/5dbed5a14bc6db6912420d5a1ae4e82e173f6a34/sampledata.csv"
col_names = [
"DATE",
"TIME",
"A",
"B",
"C",
]
dtypes = {
"A": "float64",
"B": "float64",
"C": "float64",
}
df = pd.read_csv(
data,
header=0,
names=col_names,
dtype=dtypes,
parse_dates=[["DATE", "TIME"]],
infer_datetime_format=True,
dayfirst=True,
cache_dates=True,
skipinitialspace=True,
)
fig = make_subplots(specs=[[{"secondary_y": True}]])
sample_period = (df["DATE_TIME"][1] - df["DATE_TIME"][0]).total_seconds()
step_size = 30
sample_count = len(df)
slider_positions = 60
for step in np.arange(0, slider_positions, 1):
fig.add_trace(
go.Scatter(
visible=False,
x=df["DATE_TIME"].truncate(
after=sample_count - step_size * step / sample_period - 1
),
y=df["B"].truncate(before=step_size * step / sample_period - 1),
mode="lines",
name="Offset Trace",
),
secondary_y=False,
)
fig.data[0].visible = True
fig.add_trace(
go.Scatter(
x=df["DATE_TIME"],
y=df["C"],
mode="lines",
),
secondary_y=False,
)
fig.add_trace(
go.Scatter(
x=df["DATE_TIME"],
y=df["A"],
mode="lines",
),
secondary_y=True,
)
steps = []
for i in range(1, slider_positions):
step = dict(
method="restyle", args=["visible", [False] * slider_positions + [True] * 3],
)
step["args"][1][i] = True
step["label"] = humanize.naturaldelta(timedelta(seconds=i * 30))
steps.append(step)
sliders = [
dict(
active=slider_positions,
currentvalue={"prefix": "Offset: "},
pad={"t": 250},
steps=steps,
)
]
fig.update_layout(sliders=sliders)
fig.write_html("time_offset.html", auto_open=True)