【问题标题】:Plotly: How to select scatter plot marker size and colour values from dropdown?Plotly:如何从下拉列表中选择散点图标记大小和颜色值?
【发布时间】:2021-03-03 18:45:43
【问题描述】:

我正在尝试使用内置的 plotly 小部件从 plotly express 中选择 scatterscatter_3d 中的标记大小和颜色值。我可以使用ipywidgets 来完成这项工作,但随后它将绘图重置为原始方向(3D)。但是当使用updatemenus 时,根本没有任何变化。

这是一个示例代码:

import plotly.express as px
df = px.data.iris()


fig = px.scatter_3d(df, x='sepal_length', y='sepal_width', z='petal_width',
                   color='species', size='petal_length' ,text='species_id'               )
fig.update_layout(scene_aspectmode='data')

fig.update_layout(updatemenus=[
                    dict(
                        buttons=list([
                         dict(
                             args=['size','sepal_length'],
                             label='sepal length',
                             method='update'
                         ),
                         dict(
                             args=['size','sepal_width'],
                             label='sepal width',
                             method='update'
                         )         
                        ]),
                        showactive=True,
                        )                        
                     ])

fig.show()

我尝试了args 和不同的methods 的多种变体。

这个带有ipywidgets 的例子可以工作,但如果绘图已被缩放或旋转,它会重置视图。

import plotly.express as px
import ipywidgets as widgets
from ipywidgets import interactive, interact, interact_manual, Layout

df = px.data.iris()

sel_size= widgets.Dropdown(
    options=sorted(df.columns),    
    description='Size',
    value='sepal_length'
)


sel_colour= widgets.Dropdown(
    options=sorted(df.columns),    
    description='Colour',
    value='species'
)

@interact
def get_column(size=sel_size,color=sel_colour):        
    scatter3D_fig = px.scatter_3d(df, x='sepal_length', y='sepal_width', z='petal_width',
                   color='species', size='petal_length' ,text='species_id',opacity=0.5)
    scatter3D_fig.update_layout(scene_aspectmode='data')
    scatter3D_fig.show()

根据@vestland 的回答修改,这与我想要的很接近。我可以为标记大小和颜色选择不同的数据,而无需更改相机/眼睛的位置。虽然当我为颜色选择一个分类变量时,更改标记符号只会更改一个类别。

from plotly import tools
import plotly.express as px
import plotly.graph_objects as go

import dash
import dash_core_components as dcc
import dash_html_components as html
from jupyter_dash import JupyterDash
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output


app = JupyterDash(external_stylesheets=[dbc.themes.SLATE])


# colors = px.colors.qualitative.Plotly
colors = ['blue', 'green', 'red', 'black', 'yellow']
symbols = ['circle', 'circle-open', 'square', 'square-open', 'diamond', 'diamond-open', 'cross', 'x']
columns = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species', 'species_id']

# Set up well organized controls in a dbc.Card()
controls = dbc.Card([dbc.FormGroup([dbc.Label("Color"),
                                    dcc.Dropdown(id='ctrl_color',
                                                 options= [{'label': k, 'value': k} for k in columns],
#                                                   value=colors[0]
                                                  value='species'
                                                ),
                                   ],),
                    dbc.FormGroup([dbc.Label("Symbol"),
                                   dcc.Dropdown(id='ctrl_symbol',
                                                options=[{'label': k, 'value': k} for k in symbols],
                                                value=symbols[0],
                                                ),
                                   ],),
                    dbc.FormGroup([dbc.Label("Size"),
                                   dcc.Dropdown(id='ctrl_size',
                                                options=[{'label': k, 'value': k} for k in columns],
                                                value='petal_length',
                                                ),
                                    ],)                     
                    ],
                    body=True,
                    style = {'font-size': 'large'}
                    )

# Set up the app layout using dbc.Container(), dbc.Row(), and dbc.Col()
app.layout = dbc.Container([html.H1("Marker color, symbol and size"),
                            html.Hr(),
                            html.Div(id="campos"),
                            dbc.Row([dbc.Col([controls],xs = 4),
                                     dbc.Col([dbc.Row([dbc.Col(dcc.Graph(id="market_graph")),])]),
                                    ]),
                            html.Br(),
                            ],
                            fluid=True,
                            )

# 3D figure with callbacks for color, symbol and size
@app.callback(
    [Output("campos", "children"),Output("market_graph", "figure")],
    [
        Input("market_graph", "relayoutData"),
        Input("ctrl_color", "value"),
        Input("ctrl_symbol", "value"),
        Input("ctrl_size", "value"),        
    ],
)
def history_graph(data,color, symbol, size):
    df = px.data.iris()
    fig = px.scatter_3d(df, x='sepal_length', y='sepal_width', z='petal_width',size=size,color=color)

#     fig.data[0].update(marker_color=color)
    fig.data[0].update(marker_symbol=symbol)
#     fig.data[0].update(marker_size=size)

    fig.update_layout(uirevision='constant')
    fig.update_layout(template = 'plotly_dark')
    return str(data),fig

app.run_server(mode='inline', port = 8008)

【问题讨论】:

  • 请与您的数据样本共享一个可运行的 sn-p。
  • 我已更新为使用 iris 数据集中的示例,我正在尝试设置标记大小。
  • 嗨@vestland,我接受它,那么目前不可能用plotly 做到这一点?
  • 看起来确实不是这样。而且我试过了!实际上最终我自己解决了一个类似的问题,并添加了一些细节。这肯定是 Plotly Dash 的一种可能性,但如果这可能会引起人们的兴趣......
  • 谢谢,我还需要研究 Dash

标签: python drop-down-menu plotly


【解决方案1】:

下面的代码 sn-p 将生成一个 Dash 应用程序,让您可以使用下拉菜单控制 3D 标记的颜色、符号和大小。这对于'size' 来说可能并不完美,但如果您可以使用它,我们可以更改它。

使用此设置,颜色、大小和符号通过以下方式控制:

fig.data[0].update(marker_color=color)
fig.data[0].update(marker_symbol=symbol)
fig.data[0].update(marker_size=size)

这个甜蜜的小细节照顾了:

这个带有 ipywidgets 的例子可以工作,但是如果情节有,它会重置视图 被缩放或旋转。

fig.update_layout(uirevision='constant')

情节 1:默认选择

情节 2:其他一些选择

使用 JupyterDash 和一些引导组件的完整代码

import plotly as py
import pandas as pd

from plotly import tools
import plotly.express as px
import plotly.graph_objects as go

import dash
import dash_core_components as dcc
import dash_html_components as html
from jupyter_dash import JupyterDash
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output


app = JupyterDash(external_stylesheets=[dbc.themes.SLATE])


# colors = px.colors.qualitative.Plotly
colors = ['blue', 'green', 'red', 'black', 'yellow']
symbols = ['circle', 'circle-open', 'square', 'square-open', 'diamond', 'diamond-open', 'cross', 'x']


# Set up well organized controls in a dbc.Card()
controls = dbc.Card([dbc.FormGroup([dbc.Label("Color"),
                                    dcc.Dropdown(id='ctrl_color',
                                                 options= [{'label': k, 'value': k} for k in colors],
                                                  value=colors[0]
                                                ),
                                   ],),
                    dbc.FormGroup([dbc.Label("Symbol"),
                                   dcc.Dropdown(id='ctrl_symbol',
                                                options=[{'label': k, 'value': k} for k in symbols],
                                                value=symbols[0],
                                                ),
                                   ],),
                    dbc.FormGroup([dbc.Label("Size"),
                                   dcc.Dropdown(id='ctrl_size',
                                                options=[{'label': k, 'value': k} for k in [8,10,12,14,16]],
                                                value=8,
                                                ),
                                    ],)
                    ],
                    body=True,
                    style = {'font-size': 'large'}
                    )

# Set up the app layout using dbc.Container(), dbc.Row(), and dbc.Col()
app.layout = dbc.Container([html.H1("Marker color, symbol and size"),
                            html.Hr(),
                            dbc.Row([dbc.Col([controls],xs = 4),
                                     dbc.Col([dbc.Row([dbc.Col(dcc.Graph(id="market_graph")),])]),
                                    ]),
                            html.Br(),
                            ],
                            fluid=True,
                            )

# 3D figure with callbacks for color, symbol and size
@app.callback(
    Output("market_graph", "figure"),
    [
        Input("ctrl_color", "value"),
        Input("ctrl_symbol", "value"),
        Input("ctrl_size", "value"),
    ],
)
def history_graph(color, symbol, size):
    df = px.data.iris()
    fig = px.scatter_3d(df, x='sepal_length', y='sepal_width', z='petal_width')

    fig.data[0].update(marker_color=color)
    fig.data[0].update(marker_symbol=symbol)
    fig.data[0].update(marker_size=size)

    fig.update_layout(uirevision='constant')
    fig.update_layout(template = 'plotly_dark')
    return fig

app.run_server(mode='inline', port = 8007)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 2021-04-20
    • 2021-10-28
    • 2020-12-04
    • 2016-04-07
    • 2022-01-16
    • 2021-10-13
    相关资源
    最近更新 更多