如何在单个浏览器页面上向 Dash 应用程序添加多个图表?

2022-01-21 00:00:00 python plotly plotly-dash html

如何在同一页面上添加多个显示在图片中的图表?我正在尝试将 html.Div 组件添加到以下代码以更新页面布局以在单个页面上添加更多类似的图形,但是这些新添加的图形不会显示在页面上,只有旧图形显示在图片中可见.我应该修改什么元素,比如说在浏览器的dash应用程序的单个页面上添加3次上传图像中显示的图形?

<代码>导入破折号将 dash_core_components 导入为 dcc将 dash_html_components 导入为 htmli[在此处输入图像描述][1]将 plotly.express 导入为 px将熊猫导入为 pdexternal_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']app = dash.Dash(__name__, external_stylesheets=external_stylesheets)# 假设你有一个长格式";数据框# 查看 https://plotly.com/python/px-arguments/了解更多选项df = pd.DataFrame({水果":[苹果"、橙子"、香蕉"、苹果"、橙子"、香蕉"]、数量":[4, 1, 2, 2, 4, 5],城市":[SF"、SF"、SF"、蒙特利尔"、蒙特利尔"、蒙特利尔"]})fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")app.layout = html.Div(儿童=[html.H1(children='Hello Dash'),html.Div(儿童='''Dash:Python 的 Web 应用程序框架.'''),dcc.Graph(id='示例图',图=图)])如果 __name__ == '__main__':app.run_server(debug=True)

解决方案

要多次添加同一个图形,你只需要扩展你的 app.layout.我在下面扩展了您的代码作为示例.

导入破折号将 dash_core_components 导入为 dcc将 dash_html_components 导入为 html从 dash.dependencies 导入输入、输出将熊猫导入为 pd将 plotly.express 导入为 pxexternal_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']app = dash.Dash(__name__, external_stylesheets=external_stylesheets)# 假设你有一个长格式";数据框# 查看 https://plotly.com/python/px-arguments/了解更多选项df_bar = pd.DataFrame({水果":[苹果"、橙子"、香蕉"、苹果"、橙子"、香蕉"]、数量":[4, 1, 2, 2, 4, 5],城市":[SF"、SF"、SF"、蒙特利尔"、蒙特利尔"、蒙特利尔"]})fig = px.bar(df_bar, x="Fruit", y="Amount", color="City", barmode="group")app.layout = html.Div(儿童=[# 页面顶部的所有元素html.div([html.H1(children='Hello Dash'),html.Div(儿童='''Dash:Python 的 Web 应用程序框架.'''),dcc.Graph(id='graph1',图=图),]),# 页面新行"中所有元素的新 divhtml.div([html.H1(children='Hello Dash'),html.Div(儿童='''Dash:Python 的 Web 应用程序框架.'''),dcc.Graph(id='graph2',图=图),]),])如果 __name__ == '__main__':app.run_server(debug=True)

我构建布局的方式是嵌套 html.Div 组件.对于每个图形和相应的标题、文本等,我们创建另一个 html.Div,在我们的应用程序中创建一个新的行".

要记住的一件事是,不同的组件需要唯一的 ID.在此示例中,我们将相同的图表显示了两次,但它们不是完全相同的对象.我们正在使用相同的 plotly.express 图制作两个 dcc.Graph 对象

我已经为您制作了另一个示例,其中我添加了另一个 动态 图形.每次从下拉菜单中选择新的色标时,都会更新第二个数字.这是 Dash 谎言的真正潜力.您可以在此

您的下一个问题可能是,我如何将多个数字并排放置?这就是 CSS 和样式表很重要的地方.

您已经添加了一个外部样式表 https://codepen.io/chriddyp/pen/bWLwgP.css,这使我们能够使用 className div 的组成部分.

无论屏幕大小如何,网页的宽度都设置为 12 列.因此,如果我们想要并排放置两个图形,每个图形占据 50% 的屏幕,它们需要分别填充 6 列.

我们可以通过嵌套另一个 html.Div 作为我们的上半行来实现这一点.在这个上层 div 中,我们可以有另外两个 div,我们在其中根据 classname six columns 指定样式.这会将第一行分成两半

导入破折号将 dash_core_components 导入为 dcc将 dash_html_components 导入为 html从 dash.dependencies 导入输入、输出将熊猫导入为 pd将 plotly.express 导入为 px从 jupyter_dash 导入 JupyterDashexternal_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']app = dash.Dash(__name__, external_stylesheets=external_stylesheets)# 假设你有一个长格式";数据框# 查看 https://plotly.com/python/px-arguments/了解更多选项df_bar = pd.DataFrame({水果":[苹果"、橙子"、香蕉"、苹果"、橙子"、香蕉"]、数量":[4, 1, 2, 2, 4, 5],城市":[SF"、SF"、SF"、蒙特利尔"、蒙特利尔"、蒙特利尔"]})fig = px.bar(df_bar, x="Fruit", y="Amount", color="City", barmode="group")app.layout = html.Div(儿童=[# 页面顶部的所有元素html.div([html.div([html.H1(children='Hello Dash'),html.Div(儿童='''Dash:Python 的 Web 应用程序框架.'''),dcc.Graph(id='graph1',图=图),], className='六列'),html.div([html.H1(children='Hello Dash'),html.Div(儿童='''Dash:Python 的 Web 应用程序框架.'''),dcc.Graph(id='graph2',图=图),], className='六列'),], 类名='行'),# 页面新行"中所有元素的新 divhtml.div([html.H1(children='Hello Dash'),html.Div(儿童='''Dash:Python 的 Web 应用程序框架.'''),dcc.Graph(id='graph3',图=图),], 类名='行'),])如果 __name__ == '__main__':app.run_server(debug=True)

How do I add multiple graphs show in in picture on a same page? I am trying to add html.Div components to following code to update the page layout to add more graphs like that on single page, but these newly added graphs do not get shown on a page, only old graph is shown in picture is visible. What element should I modify, to let's say to add graph shown in uploaded image 3 times on single page of dash app on browser?


import dash
import dash_core_components as dcc
import dash_html_components as html
i[enter image description here][1]mport plotly.express as px
import pandas as pd

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

# assume you have a "long-form" data frame
# see https://plotly.com/python/px-arguments/ for more options
df = pd.DataFrame({
    "Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
    "Amount": [4, 1, 2, 2, 4, 5],
    "City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"]
})

fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")

app.layout = html.Div(children=[
    html.H1(children='Hello Dash'),

    html.Div(children='''
        Dash: A web application framework for Python.
    '''),

    dcc.Graph(
        id='example-graph',
        figure=fig
    )
])

if __name__ == '__main__':
    app.run_server(debug=True)

解决方案

To add the same figure multiple times, you just need to extend your app.layout. I have extended you code below as an example.

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
import plotly.express as px

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

# assume you have a "long-form" data frame
# see https://plotly.com/python/px-arguments/ for more options
df_bar = pd.DataFrame({
    "Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
    "Amount": [4, 1, 2, 2, 4, 5],
    "City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"]
})

fig = px.bar(df_bar, x="Fruit", y="Amount", color="City", barmode="group")

app.layout = html.Div(children=[
    # All elements from the top of the page
    html.Div([
        html.H1(children='Hello Dash'),

        html.Div(children='''
            Dash: A web application framework for Python.
        '''),

        dcc.Graph(
            id='graph1',
            figure=fig
        ),  
    ]),
    # New Div for all elements in the new 'row' of the page
    html.Div([
        html.H1(children='Hello Dash'),

        html.Div(children='''
            Dash: A web application framework for Python.
        '''),

        dcc.Graph(
            id='graph2',
            figure=fig
        ),  
    ]),
])

if __name__ == '__main__':
    app.run_server(debug=True)

The way I have structured the layout is by nesting the html.Div components. For every figure and corresponding titles, text, etc. we make another html.Div that makes a new 'row' in our application.

The one thing to keep in mind is that different components need unique ids. In this example we have the same graph displayed twice, but they are not the exact same object. We are making two dcc.Graph objects using the same plotly.express figure

I have made another example for you where I have a added another figure that is dynamic. The second figure is updated every time a new colorscale is selected from the dropdown menu. This is were the real potential of Dash lies. You can read more about callback functions in this tutorial

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
import plotly.express as px

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

# assume you have a "long-form" data frame
# see https://plotly.com/python/px-arguments/ for more options
df_bar = pd.DataFrame({
    "Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
    "Amount": [4, 1, 2, 2, 4, 5],
    "City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"]
})

fig = px.bar(df_bar, x="Fruit", y="Amount", color="City", barmode="group")

# Data for the tip-graph
df_tip = px.data.tips()

app.layout = html.Div(children=[
    # All elements from the top of the page
    html.Div([
        html.H1(children='Hello Dash'),

        html.Div(children='''
            Dash: A web application framework for Python.
        '''),

        dcc.Graph(
            id='example-graph',
            figure=fig
        ),  
    ]),
    # New Div for all elements in the new 'row' of the page
    html.Div([ 
        dcc.Graph(id='tip-graph'),
        html.Label([
            "colorscale",
            dcc.Dropdown(
                id='colorscale-dropdown', clearable=False,
                value='bluyl', options=[
                    {'label': c, 'value': c}
                    for c in px.colors.named_colorscales()
                ])
        ]),
    ])
])

# Callback function that automatically updates the tip-graph based on chosen colorscale
@app.callback(
    Output('tip-graph', 'figure'),
    [Input("colorscale-dropdown", "value")]
)
def update_tip_figure(colorscale):
    return px.scatter(
        df_color, x="total_bill", y="tip", color="size",
        color_continuous_scale=colorscale,
        render_mode="webgl", title="Tips"
    )

if __name__ == '__main__':
    app.run_server(debug=True)

Your next question may be, how do i place multiple figures side by side? This is where CSS and stylesheets are important.

You have already added an external stylesheet https://codepen.io/chriddyp/pen/bWLwgP.css, which enables us to better structure our layout using the className component of divs.

The width of a web page is set to 12 columns no matter the screen size. So if we want to have two figures side by side, each occupying 50% of the screen they need to fill 6 columns each.

We can achieve this by nesting another html.Div as our top half row. In this upper div we can have another two divs in which we specify the style according to classname six columns. This splits the first row in two halves

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
import plotly.express as px
from jupyter_dash import JupyterDash

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

# assume you have a "long-form" data frame
# see https://plotly.com/python/px-arguments/ for more options
df_bar = pd.DataFrame({
    "Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
    "Amount": [4, 1, 2, 2, 4, 5],
    "City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"]
})

fig = px.bar(df_bar, x="Fruit", y="Amount", color="City", barmode="group")

app.layout = html.Div(children=[
    # All elements from the top of the page
    html.Div([
        html.Div([
            html.H1(children='Hello Dash'),

            html.Div(children='''
                Dash: A web application framework for Python.
            '''),

            dcc.Graph(
                id='graph1',
                figure=fig
            ),  
        ], className='six columns'),
        html.Div([
            html.H1(children='Hello Dash'),

            html.Div(children='''
                Dash: A web application framework for Python.
            '''),

            dcc.Graph(
                id='graph2',
                figure=fig
            ),  
        ], className='six columns'),
    ], className='row'),
    # New Div for all elements in the new 'row' of the page
    html.Div([
        html.H1(children='Hello Dash'),

        html.Div(children='''
            Dash: A web application framework for Python.
        '''),

        dcc.Graph(
            id='graph3',
            figure=fig
        ),  
    ], className='row'),
])

if __name__ == '__main__':
    app.run_server(debug=True)

相关文章