Comment créer un symbole/bouton sur un Plotly choropleth carte

0

La question

Je veux créer des boutons sur un Plotly choropleth carte comme les boutons (que mes trois flèches rouges pointent vers) sur la carte https://resources-covid19canada.hub.arcgis.com/. Lorsque le bouton est cliqué, une windows de la légende est affichée.

Vos suggestions serait très apprécié.

Merci pour votre aide!

button choropleth plotly
2021-11-22 22:01:35
1
0
  • vous pouvez obtenir le type de figure vous montrer avec plotly. Il y a plusieurs problèmes avec l'utilisation de symboles sur mapbox parcelles. Donc si vous voulez de la couleur, de la taille et de l'utilisation de différentes formes, il est nécessaire d'utiliser geojson couches
  • avoir une légende de la même façon n'est pas vraiment possible. Clairement, vous avez barre de couleur de la légende. Le choix de la taille et de la forme de marqueurs est vraiment à l'aspect visuel sans légende
  • le code complet est à la fin
    • sources de données
      • Canada COVID données par province à partir du site web lié
      • Canada province de la géométrie des limites
    • prépare des données. Calcule le pourcentage se déplace
    • les fonctions de l'utilitaire à la source SVG à partir de https://labs.mapbox.com/maki-icons/ ou https://fontawesome.com/v5.15/icons?d=gallery&p=1&m=free
    • ce code peut être encore affinée. Cache de fichiers SVG, un meilleur dimensionnement des ratios entre les grands et les petits
px.choropleth_mapbox(
    df.loc[df["SummaryDate"].eq(df["SummaryDate"].max())].merge(df_t, on="Abbreviation"),
    geojson=gdf_can.geometry,
    locations="Abbreviation",
    color="DailyTotals",
    hover_data={"Province":True, "SummaryDate":True, "Change":":.2%"},
    color_continuous_scale="BuPu"
).update_layout(
    mapbox={
        "style": "carto-positron",
        "zoom": 2,
        "center": {
            "lon": sum(gdf_can.total_bounds[[0, 2]]) / 2,
            "lat": sum(gdf_can.total_bounds[[1, 3]]) / 2,
        },
        "layers": px_marker_mapbox(
            df_t.join(gdf_can),
            color_discrete_map={
                "solid/arrow-up": "yellow",
                "solid/arrow-down": "silver",
            },
        ),
    },
    margin={"l": 0, "r": 0, "t": 0, "b": 0},
)

enter image description here

code de programme d'installation

import geopandas as gpd
import pandas as pd
import requests
import plotly.express as px
import shapely.geometry
import svgpath2mpl
import numpy as np

# create shapely multi-polygon from maki or font-awesome SVG path
def marker(name="star", source="fa"):
    def to_shapely(mpl, simplify=0):
        p = shapely.geometry.MultiPolygon(
            [shapely.geometry.Polygon(a).simplify(simplify) for a in mpl]
        )
        p = shapely.affinity.affine_transform(
            p,
            [1, 0, 0, -1, 0, 0],
        )
        scale = 1 if source == "maki" else 10 ** -2
        p = shapely.affinity.affine_transform(
            p,
            [1, 0, 0, 1, -p.centroid.x, -p.centroid.y],
        )
        return shapely.affinity.affine_transform(
            p,
            [scale, 0, 0, scale, -p.centroid.x, -p.centroid.y],
        )

    if source == "maki":
        url = f"https://raw.githubusercontent.com/mapbox/maki/main/icons/{name}.svg"
    elif source == "fa":
        url = f"https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/svgs/{name}.svg"
    svgpath = pd.read_xml(requests.get(url).text).loc[0, "d"]
    return to_shapely(svgpath2mpl.parse_path(svgpath).to_polygons())

# create mapbox layers for markers.  icon defines layer and color
def px_marker_mapbox(
    df,
    icon="icon",
    size="size",
    lat="lat",
    lon="lon",
    color_discrete_map=None,
    color_discrete_sequence=px.colors.qualitative.Plotly,
):
    layers = []
    for i, g in enumerate(df.groupby(icon)):
        m = marker(g[0])
        geoms = [
            shapely.affinity.affine_transform(
                m, [r[1][size], 0, 0, r[1][size], r[1][lon], r[1][lat]]
            )
            for r in g[1].iterrows()
        ]
        if color_discrete_map and g[0] in color_discrete_map.keys():
            color = color_discrete_map[g[0]]
        else:
            color = color_discrete_sequence[i % len(color_discrete_sequence)]
        layers.append(
            {
                "source": gpd.GeoSeries(geoms).__geo_interface__,
                "type": "fill",
                "color": color,
            }
        )

    return layers


# fmt: off
gdf_can = gpd.GeoDataFrame.from_features(requests.get("https://data.opendatasoft.com/explore/dataset/georef-canada-province@public/download/?format=geojson&timezone=Europe/London&lang=en").json())
gdf_can["lat"] = gdf_can["geo_point_2d"].apply(lambda l: l[0])
gdf_can["lon"] = gdf_can["geo_point_2d"].apply(lambda l: l[1])

# two different province codes used by COVID and geometry, get map...
df_prov = pd.read_html("https://www150.statcan.gc.ca/n1/pub/92-195-x/2011001/geo/prov/tbl/tbl8-eng.htm")[0].drop(13)
df_prov = df_prov.rename(
    columns={
        "Internationally approved alpha code (Source: Canada Post)": "Abbreviation",
        "Standard geographical classification (SGC) code": "prov_code",
    }
)

gdf_can = gdf_can.merge(df_prov.loc[:, ["prov_code", "Abbreviation"]], on="prov_code").set_index("Abbreviation")

# get COVID daily data...
df = pd.json_normalize(requests.get("https://opendata.arcgis.com/datasets/3afa9ce11b8842cb889714611e6f3076_0.geojson").json()["features"])
df = df.rename(columns={c:c.split(".")[1] for c in df.columns if len(c.split("."))==2})
df["SummaryDate"] = pd.to_datetime(df["SummaryDate"].str[0:10]) if df["SummaryDate"].dtype=="O" else df["SummaryDate"]
df = df.loc[df["SummaryDate"].ge(df["SummaryDate"].max()-pd.Timedelta(days=7)) & df["Abbreviation"].ne("CA")]
# fmt: on

# rollup changes data...
df_t = df.groupby("Abbreviation")["DailyTotals"].apply(
    lambda s: s.pct_change(periods=7).dropna()
).to_frame().rename(columns={"DailyTotals":"Change"}).assign(
    icon=lambda d: np.select(
        [d["Change"] < -0.1, d["Change"] > 0.1],
        ["solid/arrow-down", "solid/arrow-up"],
        "solid/arrows-alt-h",
    ),
    size=lambda d: d["Change"].abs()
).droplevel(1)
2021-11-23 20:11:04

Dans d'autres langues

Cette page est dans d'autres langues

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................