使用 facet_row 或在 Python 中使用 make_subplots

Remove left and right labels and paint values 1 by 1 in x-axis with Plotly that use facet_row or instead use make_subplots in Python

我正在使用 Plotly.express、plotly.subplots 和 plotly.graph_objs 来可视化一些图表,这些图表根据我传递的一些数据(数据)而变化,但我在这里很难输入代码保存代码,更易读和简化。

我想要实现的是如下图所示的图表(它是经过编辑的图像),y 轴上有一个标签“值”,右侧没有标签,x-轴将与标签“时间轴”保持原样,并且 x 轴不会将值分隔为 2 的倍数,而是 1 乘 1(并将其与从 -1 到最后一个值的行整合x轴,我在最后解释):

第一。当我使用 plotly.express 时,代码如下:

import plotly.express as px

import pandas as pd
import numpy as np

data = {
    "Name": [
        "Lamp_D_Rq", "Status", "Status", "HMI",
        "Lck_D_RqDrv3", "Lck_D_RqDrv3", "Lck_D_RqDrv3",
        "Lck_D_RqDrv3", "Lamp_D_Rq", "Lamp_D_Rq",
        "Lamp_D_Rq", "Lamp_D_Rq",
    ],
    "Value": [0, 4, 4, 2, 1, 1, 2, 2, 1, 1, 3, 3],
    "Gage": [
        "F1", "H1", "H3", "H3", "H3",
        "F1", "H3", "F1", "F1", "H3",
        "F1", "H3",
    ],
    "Id_Par": [0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0],
}

signals_df = pd.DataFrame(data)

signals_df['Count'] = signals_df.groupby('Id_Par').cumcount().add(1).mask(signals_df['Id_Par'].eq(0), 0)
signals_df['Sub'] = signals_df.index - signals_df['Count']
id_par_prev = signals_df['Id_Par'].unique()
id_par = np.delete(id_par_prev, 0)
signals_df['Prev'] = [1 if x in id_par else 0 for x in signals_df['Id_Par']]

print(signals_df)

fig = px.line(
    signals_df,
    y="Value",
    x="Sub",
    color="Name",
    hover_data=["Gage"],
    custom_data=["Gage"],
    markers=True,
    height=500,
    render_mode="svg",
    facet_row="Name"
)

fig.update_traces(line={"shape": 'hv'})
fig.update_traces(
    hovertemplate="<br>".join([
        "Gage: %{customdata[0]}",
    ]))

fig.update_layout(
        hovermode="x",
        title="Saving/Loss diagram",
        legend_title="CAN Singals",)

fig.update_xaxes(matches='x')

fig.show(config={'displaylogo': False})

在执行这第一段代码时,我得到以下内容,由子图重复的值标记,名称拼接在右侧,即使这些值具有我找到的最小名称,那里名称更长,这就是为什么我想删除,但我找不到该选项,但是,我正在考虑删除名称并将方向更改为水平,并将 x 轴值分隔为 2 的倍数,我想一一展示它们,但我找不到 Plotly 的任何这些参数或选项:

第二。当我使用 plotly.subplots 和 plotly.graph_objs 时,代码是:

from plotly.subplots import make_subplots
import plotly.graph_objs as go

import pandas as pd
import numpy as np

data = {
    "Name": [
        "Lamp", "Status", "Status", "M1",
        "Lock", "Lock", "Lock",
        "Lock", "Lamp", "Lamp",
        "Lamp", "Lamp",
    ],
    "Value": [0, 4, 4, 2, 1, 1, 2, 2, 1, 1, 3, 3],
    "Gage": [
        "A1", "B1", "B3", "B3", "B3",
        "A1", "B3", "A1", "A1", "B3",
        "A1", "B3",
    ],
    "Id_Par": [0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0],
}

signals_df = pd.DataFrame(data)

signals_df['Count'] = signals_df.groupby('Id_Par').cumcount().add(1).mask(signals_df['Id_Par'].eq(0), 0)
signals_df['Sub'] = signals_df.index - signals_df['Count']
id_par_prev = signals_df['Id_Par'].unique()
id_par = np.delete(id_par_prev, 0)
signals_df['Prev'] = [1 if x in id_par else 0 for x in signals_df['Id_Par']]
print(signals_df)

names_signals = signals_df['Name'].unique()

fig = make_subplots(rows=len(names_signals), cols=1,
                    shared_xaxes=True,
                    vertical_spacing=0.02)

for i, name_signal in enumerate(names_signals):
    fig.add_trace(go.Scatter(x=signals_df["Sub"],
                             y=signals_df["Value"],
                             line_shape='hv',
                             # facet_row="Name")
                             ))
fig.update_layout(
        hovermode="x",
        title="Saving/Loss diagram",
        legend_title="CAN Singals",)

fig.update_xaxes(matches='x')
fig.show(config={'displaylogo': False})

在第二个代码的执行中,这是对我一直在做的测试,看看是否更容易可视化数据,但它给我一个错误,它没有找到 facet_row 参数,当我取消注释时,是的,我已经在 Scatter 的帮助文件中查看了它,但我找不到类似的东西:

在这种情况下,我使用它是因为在查看 Plotly 文档时我意识到 update_traceupdate_layout 等是您可以编辑和更新这些图形参数的地方,在这里你如何使用 add_trace 似乎有点不同,但我需要先将图表按子图分开,但我找不到如何使用。

在这两种情况下,objective是来自电路的一些信号,通过名称和子图将值和图形分开,即绘制它们如何变化以及值的图形根据他们的名字在时间轴上呈现,并绘制在不同的子图中。

关于从 -1 开始到信号最后一个值的行,我尝试了以下,但它不接受它,因为它一定要我传递 [=50= 的一列] 数据框,但首先我想找到允许我在左侧 y 轴上使用单个标签绘制子图的参数,并删除右侧的名称,x 轴将其分开 1x1,然后继续这个,在我用 Matplotlib 制作的桌面应用程序中,实际上对我很有帮助,但在这种情况下,我不知道如何调用这些值,因为我试图将其放入变量并将其分配给“x”和“y” px.line 并且它不起作用:

x= np.hstack([-1, data.index.values, len(signals_df) - 1])
y= np.hstack([0, data.values, data.iloc[-1]])

希望我说的很清楚,能帮到我,非常感谢。

  • 这里嵌入了多个问题
  • px annotations 如果需要,可以从 layout 中删除。我不相信这是问题
  • 如何使用go动态生成子图。很简单,使用 enumerate() 循环数据子集来定义行。详情如下
from plotly.subplots import make_subplots
import plotly.graph_objects as go

names_signals = signals_df['Name'].unique()

fig = make_subplots(rows=len(names_signals), cols=1,
                    shared_xaxes=True,
                    vertical_spacing=0.02)

for r, (n, d) in enumerate(signals_df.groupby("Name")):
    # gemerate -1 point
    d = d.merge(pd.Series(np.arange(-1, d["Sub"].max()+1), name="Sub"), on="Sub", how="right").fillna(0, limit=1).dropna()
    fig.add_trace(go.Scatter(name=n, x=d["Sub"], y=d["Value"], line_shape="hv"), row=r+1, col=1)

# finally label axes and set tick sizes
fig.add_annotation(x=-0.05, y=.5, text="Value", xref="paper", yref="paper", textangle=270, showarrow=False)
fig.add_annotation(x=.5, y=-0.2, text="Timeline", xref="paper", yref="paper", showarrow=False)
fig.update_xaxes(dtick=1, tick0=-1)
fig.update_yaxes(dtick=1)