【发布时间】:2022-01-03 11:38:35
【问题描述】:
这是一个源自上一个问题的问题,可以在这里找到:Multiple opacities in Mapbox - Plotly for Python
我遇到了一些问题,即 Mapbox 地图上的多条轨迹有多个不透明度,每个不透明度都与数据框的特定值相关联。
在遵循 Rob 的有用答案(参见上面的链接),这导致了第一个主题的解决方案之后,我发现自己遇到了另一个问题,因为我现在想对他的代码进行一些改动。
虽然我的第一种方法是仅对迹线的不透明度进行更改,但我现在需要对不透明度和每条迹线的宽度进行更改,将它们中的每一个对应到特定数据帧上的不同值。
我继续复制粘贴 Rob 答案的第一部分,他在其中声明了一些函数并创建了一个数据框:
import requests
import geopandas as gpd
import plotly.graph_objects as go
import itertools
import numpy as np
import pandas as pd
from pathlib import Path
# get geometry of london underground stations
gdf = gpd.GeoDataFrame.from_features(
requests.get(
"https://raw.githubusercontent.com/oobrien/vis/master/tube/data/tfl_stations.json"
).json()
)
# limit to zone 1 and stations that have larger number of lines going through them
gdf = gdf.loc[gdf["zone"].isin(["1","2","3","4","5","6"]) & gdf["lines"].apply(len).gt(0)].reset_index(
drop=True
).rename(columns={"id":"tfl_id", "name":"id"})
# wanna join all valid combinations of stations...
combis = np.array(list(itertools.combinations(gdf.index, 2)))
# generate dataframe of all combinations of stations
gdf_c = (
gdf.loc[combis[:, 0], ["geometry", "id"]]
.assign(right=combis[:, 1])
.merge(gdf.loc[:, ["geometry", "id"]], left_on="right", right_index=True, suffixes=("_start_station","_end_station"))
)
gdf_c["lat_start_station"] = gdf_c["geometry_start_station"].apply(lambda g: g.y)
gdf_c["long_start_station"] = gdf_c["geometry_start_station"].apply(lambda g: g.x)
gdf_c["lat_end_station"] = gdf_c["geometry_end_station"].apply(lambda g: g.y)
gdf_c["long_end_station"] = gdf_c["geometry_end_station"].apply(lambda g: g.x)
gdf_c = gdf_c.drop(
columns=[
"geometry_start_station",
"right",
"geometry_end_station",
]
).assign(number_of_journeys=np.random.randint(1,10**5,len(gdf_c)))
gdf_c
f = Path.cwd().joinpath("SO.csv")
gdf_c.to_csv(f, index=False)
# there's an requirement to start with a CSV even though no sample data has been provided, now we're starting with a CSV
df = pd.read_csv(f)
# makes use of ravel simpler...
df["none"] = None
我的特殊问题从这里开始:当尝试创建两个“循环”(一个用于不透明度,一个用于宽度)时,我认为我可以执行以下操作:
BINS_FOR_OPACITY=10
opacity_a = np.geomspace(0.001,1, BINS_FOR_OPACITY)
BINS_FOR_WIDTH=10
width_a = np.geomspace(1,3, BINS_FOR_WIDTH)
fig = go.Figure()
# Note the double "for" statement that follows
for opacity, d in df.groupby(pd.cut(df["number_of_journeys"], bins=BINS_FOR_OPACITY, labels=opacity_a)):
for width, d in df.groupby(pd.cut(df["number_of_journeys"], bins=BINS_FOR_WIDTH, labels=width_a)):
fig.add_traces(
go.Scattermapbox(
name=f"{d['number_of_journeys'].mean():.2E}",
lat=np.ravel(d.loc[:,[c for c in df.columns if "lat" in c or c=="none"]].values),
lon=np.ravel(d.loc[:,[c for c in df.columns if "long" in c or c=="none"]].values),
line_width=width
line_color="blue",
opacity=opacity,
mode="lines+markers",
)
)
[Rob 的原始答案只有第一个 for 语句,没有第二个]
但是,上面的方法显然不起作用,因为它比它应该做的跟踪要多得多(我真的无法解释为什么,但我想这可能是因为两个for 强制执行的双循环声明)。
我发现某种解决方案可能隐藏在 pd.cut 部分中,因为我需要 类似的东西双重切割,但找不到正确执行此操作的方法.
我还设法通过以下方式创建了熊猫系列:
widths = pd.cut(df.["size"], bins=BINS_FOR_WIDTH, labels=width_a)
并迭代该系列,但得到与以前相同的结果(过多的痕迹)。
为了强调和澄清我自己,我不需要只有多个不透明度或多个宽度,但我需要同时和在同时,这就是给我带来一些麻烦的原因。
我非常感谢任何帮助
【问题讨论】:
标签: python pandas plotly mapbox