Python 如何在plotly中组合时间线图和散点图

Python 如何在plotly中组合时间线图和散点图,python,pandas,plotly,plotly-dash,Python,Pandas,Plotly,Plotly Dash,我有一个数据帧df,它包含随时间变化的值(过程数据)。我有一个数据帧ef,其中包含有开始时间和结束时间的事件(报警)。我想以一种像样的方式将它们结合在一个情节中 """ df== +---------------------+------------+------------+------------+ | | processA | processB | processC | |------------------

我有一个数据帧
df
,它包含随时间变化的值(过程数据)。我有一个数据帧
ef
,其中包含有开始时间和结束时间的事件(报警)。我想以一种像样的方式将它们结合在一个情节中

"""
df==
+---------------------+------------+------------+------------+
|                     |   processA |   processB |   processC |
|---------------------+------------+------------+------------|
| 2020-01-01 00:00:00 |    101.764 |   20.0079  |   0.978738 |
| 2020-01-01 00:01:00 |    102.241 |   93.3779  |  -0.977278 |
| 2020-01-01 00:02:00 |    100.95  |   -7.56786 |  -0.103219 |
| 2020-01-01 00:03:00 |    100.411 |    7.20218 |   1.45427  |
| 2020-01-01 00:04:00 |    100.761 |    6.08375 |   0.443863 |
+---------------------+------------+------------+------------+

ef==
+----+-----------------------------------------+---------------------+---------------------+----------+
|    | alm                                     | Start               | Finish              | almid    |
|----+-----------------------------------------+---------------------+---------------------+----------|
|  0 | alarm A something something has alarmed | 2020-01-01 00:00:30 | 2020-01-01 00:01:30 | alm_id A |
|  1 | alarm B something else happened         | 2020-01-01 00:01:30 | 2020-01-01 00:02:30 | alm_id B |
|  2 | alarm A something something has alarmed | 2020-01-01 00:02:00 | 2020-01-01 00:09:30 | alm_id A |
+----+-----------------------------------------+---------------------+---------------------+----------+
"""
我从plotly的文档中收集的内容,
.create\u gantt()
已被弃用。推荐的方法是
.timeline()
。我还没有弄清楚如何在
.timeline()
绘图中自定义任何内容,到目前为止,我所了解的是:

直接关注的问题是:如何自定义钢筋的位置和宽度。y轴上的报警信号(红色)占用了大量空间,如何更优雅地传达信息。
一个更大的问题是我是否采取了错误的方法?有没有更好的方法(一种新的图表类型,不同图表的组合)来实现这一点

PS. 起点:

import plotly.graph_objects as go
import plotly.express as px
import pandas as pd
import numpy as np
import plotly.io as pio
pio.renderers.default = "browser"

np.random.seed(0)
rowcounts = 10
df = pd.DataFrame(
    index = pd.date_range(start=pd.Timestamp('2020-01-01'), freq = 'min', periods=rowcounts, ),
    data = np.random.randn(rowcounts, 3), columns=['process'+ x for x in list('ABC')],
)
df.processA += 100
df.processB *= 50

idx = pd.date_range(start=pd.Timestamp('2020-01-01'), freq = '30S', periods=rowcounts*2, )
ef = pd.DataFrame([
    dict(alm="alarm A something something has alarmed", Start=idx[1], Finish=idx[3], almid="alm_id A"),
    dict(alm="alarm B something else happened", Start=idx[3], Finish=idx[5], almid="alm_id B"),
    dict(alm="alarm A something something has alarmed", Start=idx[4], Finish=idx[-1], almid="alm_id A")
])

"""
df==
+---------------------+------------+------------+------------+
|                     |   processA |   processB |   processC |
|---------------------+------------+------------+------------|
| 2020-01-01 00:00:00 |    101.764 |   20.0079  |   0.978738 |
| 2020-01-01 00:01:00 |    102.241 |   93.3779  |  -0.977278 |
| 2020-01-01 00:02:00 |    100.95  |   -7.56786 |  -0.103219 |
| 2020-01-01 00:03:00 |    100.411 |    7.20218 |   1.45427  |
| 2020-01-01 00:04:00 |    100.761 |    6.08375 |   0.443863 |
+---------------------+------------+------------+------------+

ef==
+----+-----------------------------------------+---------------------+---------------------+----------+
|    | alm                                     | Start               | Finish              | almid    |
|----+-----------------------------------------+---------------------+---------------------+----------|
|  0 | alarm A something something has alarmed | 2020-01-01 00:00:30 | 2020-01-01 00:01:30 | alm_id A |
|  1 | alarm B something else happened         | 2020-01-01 00:01:30 | 2020-01-01 00:02:30 | alm_id B |
|  2 | alarm A something something has alarmed | 2020-01-01 00:02:00 | 2020-01-01 00:09:30 | alm_id A |
+----+-----------------------------------------+---------------------+---------------------+----------+
"""

fig = px.timeline(
    ef, x_start="Start", x_end="Finish", y="alm", color="almid",
    color_discrete_map={
        "alm_id A": 'rgba(222, 111, 222, .2)',
        "alm_id B": 'rgba(111, 222, 222, .2)',
    }
)

myfont=dict(
    color="red",
    family="monospace",
    size=14,
)
for c in df.columns:
    fig = fig.add_trace(
        go.Scatter(
            x=df.index,
            y=df[c],
            name = c,
            yaxis = 'y2',
            hovertemplate = '%{y} <extra></extra>',
        ))
    
fig = fig.update_layout(
    xaxis=dict(
        type="date",
        domain=[0.15,1],
        range = [idx[2], idx[10]],
        rangeslider=dict(
            autorange=True,
            visible=True,
        ),
    ),
    yaxis=dict(
        title="alarms",
        titlefont=myfont,
        tickfont=myfont,
    ),
    yaxis2=dict(
        title="processes",
        anchor="free",
        overlaying="y",
        side="left",
        position=0.05
    ),
)

fig = fig.update_yaxes(showline=True, linewidth=2, linecolor='black')
fig.show()
导入plotly.graph\u对象
将plotly.express导入为px
作为pd进口熊猫
将numpy作为np导入
将plotly.io作为pio导入
pio.renderers.default=“浏览器”
np.random.seed(0)
行数=10
df=pd.DataFrame(
索引=pd.日期\范围(开始=pd.时间戳('2020-01-01'),频率='min',周期=行数,),
data=np.random.randn(rowcounts,3),columns=['process'+x代表列表中的x('ABC')],
)
df.processA+=100
df.processB*=50
idx=pd.date_范围(开始=pd.Timestamp('2020-01-01'),频率='30S',周期=行数*2,)
ef=pd.DataFrame([
dict(alm=“报警A某物已报警”,Start=idx[1],Finish=idx[3],almid=“alm_id A”),
dict(alm=“报警B发生了其他事情”,Start=idx[3],Finish=idx[5],almid=“报警B”),
dict(alm=“报警A某物已报警”,Start=idx[4],Finish=idx[-1],almid=“报警A”)
])
"""
df==
+---------------------+------------+------------+------------+
||过程A |过程B |过程C|
|---------------------+------------+------------+------------|
| 2020-01-01 00:00:00 |    101.764 |   20.0079  |   0.978738 |
| 2020-01-01 00:01:00 |    102.241 |   93.3779  |  -0.977278 |
| 2020-01-01 00:02:00 |    100.95  |   -7.56786 |  -0.103219 |
| 2020-01-01 00:03:00 |    100.411 |    7.20218 |   1.45427  |
| 2020-01-01 00:04:00 |    100.761 |    6.08375 |   0.443863 |
+---------------------+------------+------------+------------+
环境足迹==
+----+-----------------------------------------+---------------------+---------------------+----------+
|| alm |开始|结束| almid|
|----+-----------------------------------------+---------------------+---------------------+----------|
|0 |报警某物报警了| 2020-01-01 00:00:30 | 2020-01-01 00:01:30 | alm|U id A|
|1 |报警B发生了其他事情| 2020-01-01 00:01:30 | 2020-01-01 00:02:30 |报警B|
|2 |报警某物报警了| 2020-01-01 00:02:00 | 2020-01-01 00:09:30 | alm|U id A|
+----+-----------------------------------------+---------------------+---------------------+----------+
"""
图=px.1(
ef,x_start=“start”,x_end=“Finish”,y=“alm”,color=“almid”,
彩色离散映射={
“alm_id A”:“rgba(222、111、222、2)”,
“alm_id B”:“rgba(111222222.2)”,
}
)
myfont=dict(
color=“红色”,
family=“monospace”,
尺寸=14,
)
对于df.columns中的c:
图=图添加_轨迹(
走,散开(
x=df.index,
y=df[c],
name=c,
yaxis='y2',
hovertemplate='{y}',
))
图=图更新_布局(
xaxis=dict(
type=“日期”,
域=[0.15,1],
范围=[idx[2],idx[10]],
范围滑块=dict(
自动范围=真,
可见=真,
),
),
yaxis=dict(
title=“警报”,
titlefont=myfont,
tickfont=myfont,
),
yaxis2=dict(
title=“进程”,
anchor=“free”,
叠加=“y”,
side=“left”,
位置=0.05
),
)
fig=fig.update_yaxes(showline=True,linewidth=2,linecolor='black')
图2(图3)