Plotly交互式绘图python:将下拉菜单更改为输入框

Posted

技术标签:

【中文标题】Plotly交互式绘图python:将下拉菜单更改为输入框【英文标题】:Plotly interactive plot python: Change the dropdown menu to input box 【发布时间】:2021-10-23 18:30:22 【问题描述】:

我想用输入框更改下拉按钮,这样我就可以通过开始输入名称然后选择来搜索项目。到目前为止,我有一个下拉框,您可以在其中选择一个项目或同时选择所有项目。但是,我希望用户能够开始输入项目的名称,然后单击并选择他们想要显示其图表的项目。

由于我是 plotly 新手,任何建议都非常欢迎和赞赏 :)

到目前为止的情节如下:

我的代码:

def interactive_multi_plot(actual, forecast_1, forecast_2, title, addAll = True):
fig = go.Figure()
    

for column in forecast_1.columns.to_list():
    fig.add_trace(
        go.Scatter(
            x = forecast_1.index,
            y = forecast_1[column],
            name = "Forecast_SI"
        )

    )

    
    button_all = dict(label = 'All',
                  method = 'update',
                  args = ['visible': forecast_1.columns.isin(forecast_1.columns),
                           'title': 'All',
                           'showlegend':True])
    
for column in forecast_2.columns.to_list():
    fig.add_trace(
        go.Scatter(
            x = forecast_2.index,
            y = forecast_2[column],
            name = "Forecast_LSTM" 
        )

    )

    
    button_all = dict(label = 'All',
                  method = 'update',
                  args = ['visible': forecast_2.columns.isin(forecast_2.columns),
                           'title': 'All',
                           'showlegend':True])
for column in actual.columns.to_list():
    fig.add_trace(
        go.Scatter(
            x = actual.index,
            y = actual[column],
            name = "True values" 
        )

    )

    
    button_all = dict(label = 'All',
                  method = 'update',
                  args = ['visible': actual.columns.isin(actual.columns),
                           'title': 'All',
                           'showlegend':True])
    
fig.layout.plot_bgcolor = '#010028'
fig.layout.paper_bgcolor = '#010028'
def create_layout_button(column):
    return dict(label = column,
                method = 'update',
                args = ['visible': actual.columns.isin([column]),
                         'title': column,
                         'showlegend': True])
fig.update_layout(
    updatemenus=[go.layout.Updatemenu(
        active = 0,
        buttons = ([button_all] * addAll) +  list(actual.columns.map(lambda column: create_layout_button(column)))
        )
    ]     
)
# Update remaining layout properties
fig.update_layout(
    title_text=title,
    height=800,
    font = dict(color='#fff', size=12)
)


fig.show()

这是我收到的错误:

【问题讨论】:

【参考方案1】:interactive_multi_plot() 的小改动。
    对于所有三个 add_trace() 添加 meta = column 为每个分散创作 更改为 return fig 而不是 fig.show()
模拟一些数据并调用interactive_multi_plot()。我假设所有三个数据框都有相同的列
S = 100
C = 10

actual = pd.DataFrame(
    
        c: np.sort(np.random.uniform(0, 600, S))
        for c in [
            f"ab-c"
            for a, b, c in zip(
                np.random.randint(100, 200, C),
                np.random.choice(list("ABCDEF"), C),
                np.random.randint(300, 400, C),
            )
        ]
    
)

f1 = actual.assign(**c:actual[c]*1.1 for c in actual.columns)
f2 = actual.assign(**c:actual[c]*1.2 for c in actual.columns)

fig = interactive_multi_plot(actual, f1, f2, "Orders")

解决方案

使用 dash 这确实支持交互式下拉菜单 显示图的简单案例并在从 dash 下拉列表中选择的项目上定义 回调 现在可以认为 updatemenus 是多余的。我没有考虑将 updatemenus 同步回 dash 下拉菜单
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from jupyter_dash import JupyterDash

# Build App
app = JupyterDash(__name__)
app.layout = html.Div(
    [
        dcc.Dropdown(
            id="lines",
            options=["label": c, "value": c for c in ["All"] + actual.columns.tolist()],
            value="All",
        ),
        dcc.Graph(id="interactive-multiplot", figure=fig),
    ]
)

@app.callback(
    Output("interactive-multiplot", "figure"),
    Input("lines", "value"),
    State("interactive-multiplot", "figure"),
)
def updateGraphCB(line, fig):
    # filter traces...
    fig = go.Figure(fig).update_traces(visible=False).update_traces(visible=True, selector="meta":line if line!="All" else )
    # syn button to dash drop down
    fig = fig.update_layout(updatemenus=["active":0 if line=="All" else actual.columns.get_loc(line)+1])
    return fig

app.run_server(mode="inline")

【讨论】:

你好罗!非常感谢您的帮助!运行代码时收到错误:服务器不接受连接 嗨 - 哪一行?您使用的是什么运行时环境? (jupyter?) 是的,我正在使用 jupyter 笔记本。我添加了上面的错误。 好的 - 我不建议在答案中添加错误图像。错误正是它所说的,端口 8050 已被使用。在 jupyter 内核中 - 重新启动所有内核......我假设你的机器上已经有 ani python env 使用端口 8050 是的,您对答案中的错误是正确的。我道歉。我重新启动了所有内核。还是一样的错误。 :(

以上是关于Plotly交互式绘图python:将下拉菜单更改为输入框的主要内容,如果未能解决你的问题,请参考以下文章

使用下拉菜单在 Plotly 中交互式过滤数据表

如何返回由 2 个下拉列表更新的数据表作为 Plotly Python 中的输入

Plotly:如何使用下拉菜单选择图形源?

Plotly python:多项选择交互式绘图

用于情节热图的交互式 zmax?

在 python 中使用 panda 库和 Dash Plotly 创建带有标签和值的下拉菜单