【问题标题】:drop down menu with dash / plotly带有破折号/情节的下拉菜单
【发布时间】:2021-12-20 08:45:33
【问题描述】:

如何使用下拉菜单制作此代码,以便在“新案例”和 csv 文件中的其他 2 列之间进行选择

# load in new csv to merge with geodata
import pandas as pd
df = pd.read_csv("ALLCOUNTRIES-PREDICTED.csv", header=0, encoding="utf-8")
import plotly.express as px

fig = px.choropleth(df,                                   
                 locations="iso_alpha_3",
                 color="New Cases",                     # identify representing column
                 hover_name="Country",                # identify country code column                                  
                 animation_frame="Date",              # identify date column
                 projection="equirectangular",          # select projection
                 color_continuous_scale = 'Reds',    # select prefer color scale
                 range_color=[0,10000]                  # select range of dataset

                 ) 
fig.show()  
fig.write_html("example_map1.html")    

【问题讨论】:

  • 如果没有您的数据,您的问题将无法重现,因此我建议您将df 的示例上传为格式正确的文本。但是,现在我可以为您指明这个答案的方向:stackoverflow.com/questions/59406167/…
  • 已删除答案,因为 updatemenus 不可行...需要使用允许使用 dash 的东西,但评论并未表明这是可以接受的

标签: python-3.x jupyter-notebook plotly plotly-dash


【解决方案1】:
  • 来源 OWID COVID 数据。重命名列以与相关列名保持一致
  • 核心概念。为每一列构建一个图形。每个图形都包含轨迹(数据)、框架和布局。关键是每个框架名称都是唯一的,因此添加了一个后缀(a、b 或 c)
  • 整合三个数字
    • 痕迹很简单,只是从第一张图开始的痕迹
    • frames比较简单,所有图的所有frames
    • 布局从第一个图形中获取布局,没有播放/暂停按钮
  • updatemenus 是所需列的下拉列表。 args 是来自适当图形的 滑块coloraxis
  • 为每列使用了不同的色标。为每一列的 range_color 使用了不同的 max,根据基础数据计算得出
  • 播放/暂停已被删除 - 可以使用此概念使它们部分工作https://plotly.com/python/animations/#defining-button-arguments 但是这意味着您需要从 updatemenusupdatemenus 确实可以不能在 updatemenus 的完全静态结构中工作
import pandas as pd
import io, requests
import plotly.express as px
import plotly.graph_objects as go

# get OWID COVID data
dfall = pd.read_csv(
    io.StringIO(
        requests.get(
            "https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/owid-covid-data.csv"
        ).text
    )
)

# filter make data frame have same columns as question and filter to a few days..
dfall["date"] = pd.to_datetime(dfall["date"])
df = dfall.rename(
    columns={
        "iso_code": "iso_alpha_3",
        "new_cases": "New Cases",
        "location": "Country",
        "date": "Date",
    }
).loc[lambda d: d["Date"].ge("1-nov-2021")]
df["Date"] = df["Date"].dt.strftime("%Y-%b-%d")

# three columns we're going to build choropleths from
cols = ["New Cases", "new_deaths", "new_vaccinations"]

# build figures for each of the required columns
# key technique is append a suffix to animation frame so each frame has it's
# own name...
figs = [
    px.choropleth(
        df.assign(Date=lambda d: d["Date"] + f"~{suffix}"),
        locations="iso_alpha_3",
        color=c,  # identify representing column
        hover_name="Country",  # identify country code column
        animation_frame="Date",  # identify date column
        projection="equirectangular",  # select projection
        color_continuous_scale=color,  # select prefer color scale
        range_color=[
            0,
            df.groupby("Date")[c].quantile(0.75).mean(),
        ],  # select range of dataset
    )
    for c, color, suffix in zip(cols, ["Blues", "Reds", "Greens"], list("abc"))
]

# play / pause don't work as don't stop between columns..
layout = {
    k: v
    for k, v in figs[0].to_dict()["layout"].items()
    if k not in ["template", "updatemenus"]
}


# build figure from all frames, with layout excluding play/pause buttons
fig = go.Figure(
    data=figs[0].data, frames=[fr for f in figs for fr in f.frames], layout=layout
)

# finally build drop down menu...
fig = fig.update_layout(
    updatemenus=[
        {
            "buttons": [
                {
                    "label": c,
                    "method": "relayout",
                    "args": [
                        {
                            "coloraxis": col_fig.layout.coloraxis,
                            "sliders": col_fig.layout.sliders,
                        }
                    ],
                }
                for c, col_fig in zip(cols, figs)
            ]
        }
    ]
)

fig

破折号/情节解决方案

  • 使用破折号变得非常简单,只需构建与列一样多的图形
  • 带有回调的下拉菜单只选择合适的数字
import pandas as pd
import io, requests
import plotly.express as px
import plotly.graph_objects as go
import dash
from dash.dependencies import Input, Output, State
from jupyter_dash import JupyterDash

# get OWID COVID data
dfall = pd.read_csv(
    io.StringIO(
        requests.get(
            "https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/owid-covid-data.csv"
        ).text
    )
)

# filter make data frame have same columns as question and filter to a few days..
dfall["date"] = pd.to_datetime(dfall["date"])
df = dfall.rename(
    columns={
        "iso_code": "iso_alpha_3",
        "new_cases": "New Cases",
        "location": "Country",
        "date": "Date",
    }
).loc[lambda d: d["Date"].ge("1-nov-2021")]
df["Date"] = df["Date"].dt.strftime("%Y-%b-%d")

# three columns we're going to build choropleths from
cols = ["New Cases", "new_deaths", "new_vaccinations"]

# build figures for each of the required columns
figs = [
    px.choropleth(
        df,
        locations="iso_alpha_3",
        color=c,  # identify representing column
        hover_name="Country",  # identify country code column
        animation_frame="Date",  # identify date column
        projection="equirectangular",  # select projection
        color_continuous_scale=color,  # select prefer color scale
        range_color=[
            0,
            df.groupby("Date")[c].quantile(0.75).mean(),
        ],  # select range of dataset
    )
    for c, color in zip(cols, ["Blues", "Reds", "Greens"])
]

# Build App
app = JupyterDash(__name__)

app.layout = dash.html.Div(
    [
        dash.dcc.Dropdown(
            id="choropleth",
            options=[{"label": c, "value": i} for i, c in enumerate(cols)],
            value=0,
        ),
        dash.dcc.Graph(
            id="map",
        ),
    ]
)

@app.callback(Output("map", "figure"), Input("choropleth", "value"))
def updateGraph(id):
    if not id: return figs[0]
    return figs[int(id)]

# Run app and display result inline in the notebook
app.run_server(mode="inline")

【讨论】:

  • 非常感谢,但是为什么(# play / pause don't work as don't stop between columns..)有什么办法让它工作吗??
  • 其实我觉得有办法plotly.com/python/animations/#defining-button-arguments我会再深入一点
  • 无法让它工作 - 已在回答中进一步解释。我真的无法让它在纯粹的 plotly 解决方案中工作。 dashplotly 的组合会很简单,但您的问题表明需要 100% plotly 解决方案
  • 非常感谢您的帮助,非常感谢 ,, dash 和 plotly 都可以,我只需要它可以灵活地播放/暂停和下拉列表
  • 用破折号/情节解决方案更新
猜你喜欢
  • 2021-10-29
  • 1970-01-01
  • 2023-02-05
  • 2019-03-29
  • 2020-07-22
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多