【问题标题】:How to add control for single subplot in plotly?如何在情节中添加对单个子情节的控制?
【发布时间】:2021-01-13 09:48:15
【问题描述】:

在 plotly 中,我使用了一个包含多个子图的图形。 对于最后一个子图,我希望能够使用下拉菜单更改类型。

但是,下拉菜单的“restyle”动作似乎适用于整个图形? 如果我使用下拉菜单,其他子图就会消失:

=> 如何为特定的子图添加绘图控件?

=> 如何判断控件只影响特定子图的属性?

读取数据

import pandas as pd
​
# read in volcano database data
df = pd.read_csv(
    "https://raw.githubusercontent.com/plotly/datasets/master/volcano_db.csv",
    encoding="iso-8859-1",
)
​
# frequency of Country
freq = df
freq = freq.Country.value_counts().reset_index().rename(columns={"index": "x"})
​
# read in 3d volcano surface data
df_v = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/volcano.csv")

用子图初始化图形

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

fig = make_subplots(
    rows=3,
    cols=2,
    column_widths=[0.6, 0.4],
    row_heights=[0.4, 0.2, 0.4],
    specs=[
        [{"type": "scattergeo", "rowspan": 2}, {"type": "bar"}],
        [None, None],
        [None,                                 {"type": "surface"}]
    ]
)

# Add scattergeo globe map of volcano locations
scatter_geo = go.Scattergeo(
    lat=df["Latitude"],
    lon=df["Longitude"],
    mode="markers",
    hoverinfo="text",
    showlegend=False,
    marker=dict(color="crimson", size=4, opacity=0.8)
)

fig.add_trace(
    scatter_geo,
    row=1,
    col=1
)

# Add locations bar chart
bar = go.Bar(
    x=freq["x"][0:10],
    y=freq["Country"][0:10],
    marker=dict(color="crimson"),
    showlegend=False
)

fig.add_trace(
    bar,
    row=1,
    col=2
)

# Add 3d surface of volcano
surface_3d = go.Surface(
    z=df_v.values.tolist(),
    showscale=False
)

fig.add_trace(
    surface_3d,
    row=3,
    col=2
)
fig

添加控件

# Add dropdown

updatemenu = dict(
    buttons=list([
        dict(
            args=["type", "surface"],
            label="3D Surface",
            method="restyle"
        ),
        dict(
            args=["type", "heatmap"],
            label="Heatmap",
            method="restyle"
        )
    ]),
    direction="down",
    pad={"r": 10, "t": 10},
    showactive=True,  
    x=1,
    y=0.4
)

fig['layout'].update(
    updatemenus=[{}, {}, {}, {}, {}, updatemenu]
)

#Add slider

steps = []
for i in range(10):
    step = dict(
        method="update",
        args=[{"title": "Slider switched to step: " + str(i)}],  # layout attribute
    )
    steps.append(step)
    
slider = dict(
    active=10,
    currentvalue={"prefix": "Frequency: "},
    pad={"t": 50},
    steps=steps
)

fig.update_layout(
    sliders=[slider]
)

其他样式

# Update geo subplot properties
fig.update_geos(
    projection_type="orthographic",
    landcolor="white",
    oceancolor="MidnightBlue",
    showocean=True,
    lakecolor="LightBlue"
)

# Rotate x-axis labels
fig.update_xaxes(tickangle=45)

# Set theme, margin, and annotation in layout
fig.update_layout(
    autosize=False,
    width=800,
    height=500,
    template="plotly_dark",
    margin=dict(r=10, t=25, b=40, l=60),
    scene_camera_eye=dict(x=2, y=2, z=0.3),
    annotations=[
        dict(
            text="Source: NOAA",
            showarrow=False,
            xref="paper",
            yref="paper",
            x=0,
            y=0)
    ]
)
fig.show()

【问题讨论】:

    标签: controls plotly subplot


    【解决方案1】:

    很遗憾,这不是一个完整的答案。但希望我将要向您展示的内容将在您的道路上对您有所帮助。您会看到,您可以通过该子图中包含的轨迹指定要编辑的子图。您可以通过adding an integerargs() 中执行此操作,如下所示:

    buttons=list([
        dict(
            args=["type", "surface", [2]],
            label="3D Surface",
            method="restyle"
        )
    

    [2] 引用了您在fig.data 中的跟踪位置:

    (Scattergeo({
         'geo': 'geo',
         'hoverinfo': 'text',
         'lat': array([ 34.5  , -23.3  ,  14.501, ...,  15.05 ,  14.02 ,  34.8  ]),
         'lon': array([ 131.6  ,  -67.62 ,  -90.876, ...,   42.18 ,   42.75 , -108.   ]),
         'marker': {'color': 'crimson', 'opacity': 0.8, 'size': 4},
         'mode': 'markers',
         'showlegend': False
     }),
     Bar({
         'marker': {'color': 'crimson'},
         'showlegend': False,
         'x': array(['United States', 'Russia', 'Indonesia', 'Japan', 'Chile', 'Ethiopia',
                     'Papua New Guinea', 'Philippines', 'Mexico', 'Iceland'], dtype=object),
         'xaxis': 'x',
         'y': array([184, 169, 136, 111,  87,  57,  54,  49,  41,  38], dtype=int64),
         'yaxis': 'y'
     }),
     Surface({
         'scene': 'scene',
         'showscale': False,
    

    问题是,在你的情况下这样做会触发一些 非常 特殊行为:当按钮设置为热图时,数据变成 Bart of Bar图

    更奇怪的是,当你再次选择 3D Surface 时,它看起来应该是这样的:

    老实说,我不知道是什么原因造成的。在下面的完整代码 sn-p 中查看自己,看看你能做些什么。也许我们最终能够弄清楚......

    完整代码:

    from plotly.subplots import make_subplots
    import plotly.graph_objects as go
    
    import pandas as pd
    
    # read in volcano database data
    df = pd.read_csv(
        "https://raw.githubusercontent.com/plotly/datasets/master/volcano_db.csv",
        encoding="iso-8859-1",
    )
    
    # frequency of Country
    freq = df
    freq = freq.Country.value_counts().reset_index().rename(columns={"index": "x"})
    
    # read in 3d volcano surface data
    df_v = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/volcano.csv")
    df_v
    
    fig = make_subplots(
        rows=3,
        cols=2,
        column_widths=[0.6, 0.4],
        row_heights=[0.4, 0.2, 0.4],
        specs=[
            [{"type": "scattergeo", "rowspan": 2}, {"type": "bar"}],
            [None, None],
            [None,                                 {"type": "surface"}]
        ]
    )
    
    # Add scattergeo globe map of volcano locations
    scatter_geo = go.Scattergeo(
        lat=df["Latitude"],
        lon=df["Longitude"],
        mode="markers",
        hoverinfo="text",
        showlegend=False,
        marker=dict(color="crimson", size=4, opacity=0.8)
    )
    
    fig.add_trace(
        scatter_geo,
        row=1,
        col=1
    )
    
    # Add locations bar chart
    bar = go.Bar(
        x=freq["x"][0:10],
        y=freq["Country"][0:10],
        marker=dict(color="crimson"),
        showlegend=False
    )
    
    fig.add_trace(
        bar,
        row=1,
        col=2
    )
    
    # Add 3d surface of volcano
    surface_3d = go.Surface(
        z=df_v.values.tolist(),
        showscale=False
    )
    
    fig.add_trace(
        surface_3d,
        row=3,
        col=2
    )
    
    # Add dropdown
    
    updatemenu = dict(
        buttons=list([
            dict(
                args=["type", "surface", [2]],
                label="3D Surface",
                method="restyle"
            ),
            dict(
                args=["type", "heatmap", [2]],
                label="Heatmap",
                method="restyle"
            )
        ]),
        direction="down",
        pad={"r": 10, "t": 10},
        showactive=True,  
        x=1,
        y=0.4
    )
    
    fig['layout'].update(
        updatemenus=[{}, {}, {}, {}, {}, updatemenu]
    )
    
    #Add slider
    
    steps = []
    for i in range(10):
        step = dict(
            method="update",
            args=[{"title": "Slider switched to step: " + str(i)}],  # layout attribute
        )
        steps.append(step)
        
    slider = dict(
        active=10,
        currentvalue={"prefix": "Frequency: "},
        pad={"t": 50},
        steps=steps
    )
    
    fig.update_layout(
        sliders=[slider]
    )
    
    # Update geo subplot properties
    fig.update_geos(
        projection_type="orthographic",
        landcolor="white",
        oceancolor="MidnightBlue",
        showocean=True,
        lakecolor="LightBlue"
    )
    
    # Rotate x-axis labels
    fig.update_xaxes(tickangle=45)
    
    # Set theme, margin, and annotation in layout
    fig.update_layout(
        autosize=False,
        width=800,
        height=500,
        template="plotly_dark",
        margin=dict(r=10, t=25, b=40, l=60),
        scene_camera_eye=dict(x=2, y=2, z=0.3),
        annotations=[
            dict(
                text="Source: NOAA",
                showarrow=False,
                xref="paper",
                yref="paper",
                x=0,
                y=0)
        ]
    )
    fig.show()
    

    【讨论】:

      猜你喜欢
      • 2021-04-14
      • 1970-01-01
      • 2019-04-25
      • 1970-01-01
      • 2019-05-03
      • 1970-01-01
      • 2021-05-08
      • 2014-07-12
      • 2018-03-30
      相关资源
      最近更新 更多