Jak vytvořit symbol/tlačítko na Plotly choropleth map

0

Otázka

Chci vytvořit tlačítka na Plotly choropleth map jako tlačítka (to, že moje tři červené šipky ukazují) na mapě https://resources-covid19canada.hub.arcgis.com/. Když je klepnutí na tlačítko, windows legenda je zobrazena.

Vaše návrhy by velmi ocenil.

Děkuji za vaši pomoc!

button choropleth plotly
2021-11-22 22:01:35
1
0
  • můžete dosáhnout typ postavy jste show s plotly. Existuje několik otázek s pomocí symbolů na mapbox pozemků. Proto, pokud chcete, barvu, velikost a použití různých tvarů, je nutné použít geojson vrstev
  • s legendou v podobné cestě není opravdu možné. Jasně máte colorbar legenda. Na změnu velikosti a tvaru značek je to opravdu až na vizuální stránku bez legenda
  • kompletní kód je na konci
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

nastavení kódu

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

V jiných jazycích

Tato stránka je v jiných jazycích

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