【问题标题】:Plotly: How to make a plotly dropdown menu for figures with wholly different data and layouts?Plotly:如何为具有完全不同数据和布局的图形制作一个绘图下拉菜单?
【发布时间】:2021-03-18 07:24:37
【问题描述】:

我正在尝试使用从一系列完全不相关的图形中选择的下拉菜单制作交互式绘图(即依赖于不同数据结构且布局非常不同的绘图)。我见过的所有下拉菜单示例都基于一组数据或多个数据集,但使用相对简单的绘图布局。这不适用于我试图合并数十个具有非常不同布局和基础数据的图的情况。下面是我试图合并的地块的一个工作示例。每个地块的布局都大不相同:

import plotly.graph_objs as go
import plotly.express as px
import pandas as pd

# Prep some fake data for a bar graph
df1 = pd.DataFrame(dict(
    bar_y = ['Bar1', 'Bar2'],
    bar_x = [2,3],
    bar_z = [1,2]
))

# Make bar graph
fig1 = px.bar(df1, 
              x="bar_x", 
              y='bar_y',
              color='bar_z',
              orientation='h',
)    

# Add layout attributes
fig1.update_layout(
    xaxis_title="<b> Bar graph title <b>",
    yaxis_title="<b> Bar x axis <b>",
    legend_title="<b> Bar y axis <b>",        
    xaxis = dict(
        showgrid=True,
        ticks="",
        showline = False,
        gridcolor = 'white'
    )
)       

# Prep some fake data for a line graph
df2 = pd.DataFrame(dict(
    line_y = [3,2,1, 1,2,3],
    line_x = [1,2,3,1,2,3],
    line_group = ['line1','line1','line1','line2','line2','line2']
))

# Make an ugly line graph
fig2 = px.line(
    df2,
    x= 'line_x',
    y= 'line_y',
    color = 'line_group'
)

# Add a number of layout attributes that are distinct from those above
fig2.update_layout(
    shapes=[dict(
      type= 'line',
      fillcolor = 'black',
      line_width=2,
      yref= 'y', y0= 0, y1= 0,
      xref= 'x', x0= 1, x1= 3,
    )],
    xaxis_title="<b> Line graph title <b>",
    yaxis_title="<b> Line x axis <b>",
    legend_title="<b> Line y axis <b>",
    template='simple_white',
    hoverlabel=dict(bgcolor="white")
)


# Create a dropdown menu. Below is close to what I'd like to do, but the data statements are not working correctly and the shape in fig2 is causing problems...
fig3 = go.Figure()
fig3.update_layout(
    updatemenus=[
        dict(
            active=0,
            buttons=list([
                dict(label="Bar Graph",
                     method="update",
                     args=[fig1.to_dict()['data'],
                           fig1.to_dict()['layout']]
                    ),
                dict(label="Line Graph",
                     method="update",
                     args=[fig2.to_dict()['data'],
                           fig2.to_dict()['layout']]
                    ),
        ]))
    ]                           
)

看来我几乎能够根据每个原始图的布局正确更新每个下拉组成图的布局。但是,是否可以通过这种方法更新数据 也一样?

【问题讨论】:

  • 如何你是如何使用你的数字的?也许是 JupyterLab?
  • 谢谢@vestland。我希望只是将输出写入 html 文件。我假设您暗示使用 dcc 最容易完成我想要的操作?我认为在这一点上可能是必要的。我能够通过保持布局参数、将所有内容绘制为不可见以及让数据语句改变给定跟踪的可见性来完成类似于上述的事情,但我正在使用的真实示例需要多个交互下拉菜单来选择对象可见性。
  • 没有花太多时间在这里查看细节,我相信使用 Plotly Dash 或 JupyterDash 最容易完成。如果你愿意,我会看看我能做什么。
  • 哇@vestland。是的,我非常感谢!
  • 另外,如果可能的话,最好使用 plotly dash

标签: python drop-down-menu plotly plotly-dash plotly-python


【解决方案1】:

我可能在这里完全错过了重点。在这种情况下,释放 Dash 应用程序也可能是矫枉过正。但我想向您展示以下设置如何使您能够使用dcc.Dropdown() 返回完全不同的图形对象。下面的代码 sn-p 将生成以下应用程序:

如果你现在选择fig2,你会得到这个:

如果这是您可以使用的东西,我们可以讨论更多细节。此外,带有非常宽的下拉按钮的设计当然不是最漂亮的,但我认为设计不是这里的主要目标。

完整代码:

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output
import numpy as np
from plotly.subplots import make_subplots
import plotly.express as px

# Prep some fake data for a bar graph
df1 = pd.DataFrame(dict(
    bar_y = ['Bar1', 'Bar2'],
    bar_x = [2,3],
    bar_z = [1,2]
))

# Make bar graph
fig1 = px.bar(df1, 
              x="bar_x", 
              y='bar_y',
              color='bar_z',
              orientation='h',
)    

# Add layout attributes
fig1.update_layout(
    xaxis_title="<b> Bar graph title <b>",
    yaxis_title="<b> Bar x axis <b>",
    legend_title="<b> Bar y axis <b>",        
    xaxis = dict(
        showgrid=True,
        ticks="",
        showline = False,
        gridcolor = 'white'
    )
)       

# Prep some fake data for a line graph
df2 = pd.DataFrame(dict(
    line_y = [3,2,1, 1,2,3],
    line_x = [1,2,3,1,2,3],
    line_group = ['line1','line1','line1','line2','line2','line2']
))

# Make an ugly line graph
fig2 = px.line(
    df2,
    x= 'line_x',
    y= 'line_y',
    color = 'line_group'
)

# Add a number of layout attributes that are distinct from those above
fig2.update_layout(
    shapes=[dict(
      type= 'line',
      fillcolor = 'black',
      line_width=2,
      yref= 'y', y0= 0, y1= 0,
      xref= 'x', x0= 1, x1= 3,
    )],
    xaxis_title="<b> Line graph title <b>",
    yaxis_title="<b> Line x axis <b>",
    legend_title="<b> Line y axis <b>",
    template='simple_white',
    hoverlabel=dict(bgcolor="white")
)

# app = JupyterDash(__name__)
app = dash.Dash()
figs = ['fig1', 'fig2']

app.layout = html.Div([
    html.Div([
        dcc.Graph(id='plot'),

        html.Div([
            dcc.Dropdown(
                id='variables',
                options=[{'label': i, 'value': i} for i in figs],
                value=figs[0]
            )
        ])
    ])
])

@app.callback(
    Output('plot', 'figure'),
    [Input('variables', 'value')])

def update_graph(fig_name):

    if fig_name == 'fig1':
#         fig=go.Figure(go.Scatter(x=[1,2,3], y = [3,2,1]))
        return fig1


    if fig_name == 'fig2':
#         fig=go.Figure(go.Bar(x=[1,2,3], y = [3,2,1]))
        return fig2
        
# app.run_server(mode='external', debug=True)
app.run_server(debug=True,
           use_reloader=False # Turn off reloader if inside Jupyter
          )  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-04
    • 2018-03-06
    • 2021-03-13
    • 1970-01-01
    • 2021-03-11
    • 2022-01-13
    • 1970-01-01
    • 2021-07-28
    相关资源
    最近更新 更多