Plotly update_menus隐藏痕迹问题

问题描述 投票:0回答:1

在这里使用 Python 和 StackOverflow 的 Plotly 新手。我创建了一个图形,其中包含一些箱形图、一个散点图和一些可以中继的元素。

我的数据有差距,我想使用下拉列表选择打开和关闭图表中的显示(见图 1)。

Image 1

在一种情况下,我可以成功隐藏间隙,但散点图会丢失其 X 轴值并在标记数据结束后绘制(参见图 2)。这是由这行代码产生的:

dict(label="Exclude missing data", method="update", args=[{"x":df.Run[x_some],"visible": x_some}])

Image 2

在另一种情况下,我可以隐藏数据中的间隙,散点图有效,但“隐藏”的 X 轴标签移动到图表的末尾(见图 3)。这是由这行代码产生的:

dict(label="Exclude missing data", method="update", args=[{"visible": x_some}])

Image 3

关于我做错了什么以及如何解决这个问题有什么提示吗?

请在下面找到一些示例代码:

import pandas as pd
import numpy as np
import plotly.io as pio
import datetime as dt
import plotly.graph_objects as go

pio.renderers.default = 'browser'
pd.options.plotting.backend = "plotly"
fig = go.Figure()
N = 100
ydata = np.random.randint(600, 1200, size=(100, 5))
x = ["R"+str(i) for i in range(len(ydata))]
df = pd.DataFrame(ydata, columns=["M1", "M2", "M3", "M4", "M5"])
df["X"] = x
gaps = np.r_[20:40, 60:70]
df.iloc[gaps, 0:5] = np.nan
df["Mean"] = df.iloc[:, 0:5].mean(axis=1).round(0)
cols = df.columns.str.contains("M")

# %% figure setup
layout = dict(
    height=700, width=1500,
    xaxis_title="Run",
    xaxis=dict(autorange=False, range=[0, N], type="category"),
    yaxis=dict(autorange=True),
    font=dict(family="Courier New, monospace", size=12, color="RebeccaPurple"),
    showlegend=False
)

fig.layout = layout

mean_line = go.Scatter(x=df.X, y=df.Mean, connectgaps=True, mode='lines+markers', name='Mean line', showlegend=False)

boxes = [go.Box(name=df.X[i], y=df.iloc[i, cols], boxpoints=False, boxmean=True, notched=True, showlegend=False) for i in range(N)]

fig.add_traces(boxes)

x_all = df.index == df.index
x_some = (df.Mean > 0).values

fig.add_trace(mean_line)

fig.update_layout(updatemenus=[
    dict(type="dropdown", direction="down", buttons=list([
        dict(label="Include missing data", method="update", args=[{"visible": x_all}]),
        dict(label="Exclude missing data", method="update", args=[{"visible": x_some}])
    ]), pad={"l": 10, "t": 10}, showactive=True, x=0.23, xanchor="left", y=1.1, yanchor="top")])

z = fig.to_dict()
fig.show()
plotly visualization plotly-python
1个回答
0
投票

发生这种情况的原因是因为您忘记了最后一条痕迹,即散点,它仍然包括

NaN
的 x 值。 (有 100 个框轨迹和 1 个散点轨迹,所以
x_all
x_some
实际上应该有长度 101 – 在你的原始代码中,这两个布尔数组的长度为 100,但 plotly 假设你的意思是显示最后一个散点轨迹)

为了解决这个问题,我们可以添加另一个散点图,删除缺失值——我们可以让它默认不可见,只有当您从下拉列表中选择

"Exclude missing data"
时才显示这个散点。

注意:

x_all
x_some
现在的长度为 102。
x_all
应该看起来像
[True,... True, True, False]
,因为我们显示了前 100 个箱线图,然后显示了第一个没有丢弃空值的散点图,但随后不显示删除了空值的第二个散点图。并且
x_some
应该看起来像
[True...False... False... True, False, True]
因为一些空的箱线图痕迹不会被显示,然后我们不显示没有空值丢弃的第一个散点,但显示第二个散点有空值丢弃。

import pandas as pd
import numpy as np
import plotly.io as pio
import datetime as dt
import plotly.graph_objects as go

pio.renderers.default = 'browser'
pd.options.plotting.backend = "plotly"
fig = go.Figure()
N = 100
ydata = np.random.randint(600, 1200, size=(100, 5))
x = ["R"+str(i) for i in range(len(ydata))]
df = pd.DataFrame(ydata, columns=["M1", "M2", "M3", "M4", "M5"])
df["X"] = x
gaps = np.r_[20:40, 60:70]
df.iloc[gaps, 0:5] = np.nan
df["Mean"] = df.iloc[:, 0:5].mean(axis=1).round(0)
cols = df.columns.str.contains("M")

# figure setup
layout = dict(
    height=700, width=1500,
    xaxis_title="Run",
    xaxis=dict(autorange=False, range=[0, N], type="category"),
    yaxis=dict(autorange=True),
    font=dict(family="Courier New, monospace", size=12, color="RebeccaPurple"),
    showlegend=False
)

fig.layout = layout

mean_line = go.Scatter(x=df.X, y=df.Mean, connectgaps=True, mode='lines+markers', name='Mean line', showlegend=False)

## create mean line with excluded values missing (not visible by default)
df_non_null = df.dropna()
mean_line_exclude_missing = go.Scatter(x=df_non_null.X, y=df_non_null.Mean, connectgaps=False, mode='lines+markers', name='Mean line', showlegend=False, visible=False)

boxes = [go.Box(name=df.X[i], y=df.iloc[i, cols], boxpoints=False, boxmean=True, notched=True, showlegend=False) for i in range(N)]

fig.add_traces(boxes)

x_all = df.index == df.index
x_all = np.append(x_all, [True, False])

x_some = (df.Mean > 0).values
x_some = np.append(x_some, [False, True])

## the last two traces will be the mean line, and the mean line (with nulls excluded)
fig.add_trace(mean_line)
fig.add_trace(mean_line_exclude_missing)

fig.update_layout(updatemenus=[
    dict(type="dropdown", direction="down", buttons=list([
        dict(label="Include missing data", method="update", args=[{"visible": x_all}]),
        dict(label="Exclude missing data", method="update", args=[{"visible": x_some}])
    ]), pad={"l": 10, "t": 10}, showactive=True, x=0.23, xanchor="left", y=1.1, yanchor="top")])

z = fig.to_dict()
fig.show()

© www.soinside.com 2019 - 2024. All rights reserved.