我正在try 分配一个核对表,允许用户可视化JSON边界文件.我有一个散点图,其中用户要过滤Cat中的唯一值.我的目标是实现相同的输出,但用于绘制边界文件.此外,散点图框应该从no个边界文件开始,直到用户 Select 一个或多个.

import dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
import plotly.express as px
import plotly.graph_objs as go
import pandas as pd
import geopandas as gpd
import json

gdf_poly = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))
gdf_poly = gdf_poly.drop('name', axis = 1)

# subset African continent
Afr_gdf_area = gdf_poly[gdf_poly['continent'] == 'Africa'].reset_index(drop = True)

# subset European continent
Eur_gdf_area = gdf_poly[gdf_poly['continent'] == 'Europe'].reset_index(drop = True)

data = pd.DataFrame({
    'Cat': ['t', 'y', 'y', 'y', 'f', 'f', 'j', 'k', 'k', 'k', 's', 's', 's', 's', 'f', 'j', 'k', 'f', 'j', 'k'],
    'LAT': [5, 5, 5, 6.2, 4.3, 5.7, 14, 7, 7, 7, 7, 8.5, 19, 15, 16, 18, 17, 15, 16, 7],
    'LON': [10, 10, 10, 11.1, 9.8, 11.4, 3, 3, 3, 3, 3, 8.8, 8, 15, 8, 17, 8, 6, 16, 7],
})


external_stylesheets = [dbc.themes.SPACELAB, dbc.icons.BOOTSTRAP]

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

app.layout = dbc.Container([
    dbc.Row([
        dbc.Col([html.Label('Cats', style = {'paddingTop': '2rem', 'display': 'inline-block'}),
                 dcc.Checklist(
                     id = 'Cats',
                     options = [
                         {'label': 't', 'value': 't'},
                         {'label': 'y', 'value': 'y'},
                         {'label': 'f', 'value': 'f'},
                         {'label': 'j', 'value': 'j'},
                         {'label': 'k', 'value': 'k'},
                         {'label': 's', 'value': 's'},
                     ],
                     value = ['t', 'y', 'f', 'j', 'k', 's'],
                 ),
                 ], 
                 width = 2),
            
                html.Label('Polygon', style = {'paddingTop': '1rem'}),
                dcc.Checklist(
                    id = 'polygons',
                    options = [
                             {'label': 'Afr', 'value': 'Afr'},
                             {'label': 'Eur', 'value': 'Eur'},                          
                             ],
                    value = ['Afr', 'Eur'],
                    #clearable=True
                ),
                 dbc.Col([
                         html.Div(dcc.Graph(id = 'chart', style = {'height':800}))
                        ], width = 5)
    ])
], fluid = True)

df = data

@app.callback(
     Output('chart', 'figure'),
    [Input("Cats", "value"),
     Input("polygons", "value"),
    ],
    )

def scatter_chart(cats, polygon):

    dff = df[df['Cat'].isin(cats)]

    data = px.scatter_mapbox(data_frame = dff,
                             lat = 'LAT',
                             lon = 'LON',
                             color = 'Cat',
                             zoom = 1,
                             mapbox_style = 'carto-positron',
                             )

    if polygon == 'Afr':
    
        data.update_layout(mapbox={
            "layers": [
                {"source": json.loads(Afr_gdf_area.geometry.to_json()),
                    "below": "traces",
                    "type": "fill",
                    "color": "orange",
                    "opacity" : 0.1,
                    "line": {"width": 1}
                },
            ],
        })    

    elif polygon == 'Eur':
    
        data.update_layout(mapbox={
            "layers": [
                {"source": json.loads(Eur_gdf_area.geometry.to_json()),
                    "below": "traces",
                    "type": "fill",
                    "color": "purple",
                    "opacity" : 0.1,
                    "line": {"width": 0.2}
                },
            ],
        })    

    else:
        pass

    fig = go.Figure(data = data)

    return fig


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

推荐答案

您当前的代码没有划定界限,因为您的支票使用了polygon:

if polygon == 'Afr':
  ...
elif polygon == 'Eur':
  ...

这些条件永远不会求值为True,因为polygon引用的是dcc.CheckListvalue属性,该属性始终是一个列表:

值(字符串列表|数字|布尔值;可选):当前选定的值.

https://dash.plotly.com/dash-core-components/checklist

所以你是在做这个['Afr'] == 'Afr'的比较.

由于您指出:

...散点图框应该从没有边界文件开始,直到用户 Select 一个或多个.

我建议您将polygons dcc.CheckList的默认值设置为空列表:

dcc.Checklist(
    id="polygons",
    options=[
      {"label": "Afr", "value": "Afr"},
      {"label": "Eur", "value": "Eur"},
    ],
    value=[]
)

然后,在您的回调中,您可以这样做:

@app.callback(
    Output("chart", "figure"), 
    Input("Cats", "value"), 
    Input("polygons", "value")
)
def scatter_chart(cats, polygons):
    dff = df[df["Cat"].isin(cats)]

    data = px.scatter_mapbox(
        data_frame=dff,
        lat="LAT",
        lon="LON",
        color="Cat",
        zoom=1,
        mapbox_style="carto-positron",
    )

    polygon_mapping = {
        "Afr": {"area": Afr_gdf_area, "line-width": 1, "color": "orange"},
        "Eur": {"area": Eur_gdf_area, "line-width": 0.2, "color": "purple"},
    }

    layers = []
    for polygon in polygons:
        p = polygon_mapping[polygon]
        layers.append(
            {
                "source": json.loads(p["area"].geometry.to_json()),
                "below": "traces",
                "type": "fill",
                "color": p["color"],
                "opacity": 0.1,
                "line": {"width": p["line-width"]},
            }
        )

    data.update_layout(mapbox={"layers": layers})

    fig = go.Figure(data=data)

    return fig

在上面的代码中,我用一个字典和一个循环替换了if语句.对于每个选中的边界复选框,我们将一个层添加到层列表中,并使用该列表来更新图的MapBox层.

Python相关问答推荐

如何通过多2多字段过滤查询集

为什么tkinter框架没有被隐藏?

如何删除索引过go 的lexsort深度可能会影响性能?' &>

删除所有列值,但判断是否存在任何二元组

将输入管道传输到正在运行的Python脚本中

为什么默认情况下所有Python类都是可调用的?

OR—Tools CP SAT条件约束

如何在Raspberry Pi上检测USB并使用Python访问它?

NumPy中条件嵌套for循环的向量化

在ubuntu上安装dlib时出错

joblib:无法从父目录的另一个子文件夹加载转储模型

在Python中调用变量(特别是Tkinter)

循环浏览每个客户记录,以获取他们来自的第一个/最后一个渠道

处理Gekko的非最优解

Python 3试图访问在线程调用中实例化的类的对象

如何根据rame中的列值分别分组值

在Python中控制列表中的数据步长

提取数组每行的非零元素

用来自另一个数据框的列特定标量划分Polars数据框中的每一列,

通过对列的其余部分进行采样,在Polars DataFrame中填充_null`?