python - 如何使用 Python 在 map 上绘制可视化线串?

标签 python pandas geopandas plotly-express

我有一些来自 Lng 和 lat 的坐标,我将它们组合成一个 Linestring。

线串由 2 个点组成。从一点starting=origin从一点ending = destination .

这是线串列的代码

erg2['Linestring'] = erg2.apply(lambda x: LineString([(x['latitude_origin'], x['longitude_origin']), (x['latitude_destination'], x['longitude_destination'])]), axis = 1)

我正在尽一切努力绘制从起点到终点的线串,但没有任何好的结果..\

你会帮我很多的!\

这是数据框 erg2使用 lng 和 lat 以及组合的 Linestrings ... 我怎样才能在 map 上绘制它们。 origin 和 destination 列中的数字是城市的位置 ID..

作为一个经验丰富的程序员,你会怎么画。具有散点或组合线串的两点?? 接下来我将放入我的 dataframe.head()。希望它是读者友好的:)) 通常 df 有 [19600 行 x 8 列]

<表类="s-表"> <头> 起源 目的地 移动 longitude_origin latitude_origin <正文> 88 88 20 13.481016 52.457055 88 89 0 13.481016 52.457055 88 110 0 13.481016 52.457055 88 111 0 13.481016 52.457055 88 112 0 13.481016 52.457055 87 83 0 13.479667 52.479600
<表类="s-表"> <头> 经度_目的地 latitude_destination 线串 <正文> 13.481016 52.457055 线串 (52.45705489204205 13.4810161067992... 13.504075 52.443923 线串 (52.45705489204205 13.4810161067992... 13.613772 52.533194 线串 (52.45705489204205 13.4810161067992... 13.586891 52.523562 线串 (52.45705489204205 13.4810161067992... 13.559341 52.507418 线串 (52.45705489204205 13.4810161067992... 13.481016 52.457055 线串 (52.45705489204205 13.4810161067992...

我正在尝试使用@RobRaymond 的 geopandas 示例代码绘制线条

结果显示没有意义的行.. 这是输出:

enter image description here

所有行在悬停中都有此描述,所有行都从 87-... 在我的数据框中,您看到我们有 origin 88 等...

根据运动绘制线条也很重要。由于不需要绘制零移动... 我真的希望我把问题说清楚了。这真的有点超出我的理解范围了......

提前致谢。

最佳答案

import requests, io, json
import geopandas as gpd
import shapely.geometry
import pandas as pd
import numpy as np
import itertools
import plotly.express as px

# get some public addressess - hospitals.  data that has GPS lat / lon
dfhos = pd.read_csv(io.StringIO(requests.get("http://media.nhschoices.nhs.uk/data/foi/Hospital.csv").text),
    sep="¬",engine="python",).loc[:, ["OrganisationName", "Latitude", "Longitude"]]

a = np.arange(len(dfhos))
np.random.shuffle(a)
# establish N links between hospitals
N = 10
df = (
    pd.DataFrame({0:a[0:N], 1:a[25:25+N]}).merge(dfhos,left_on=0,right_index=True)
    .merge(dfhos,left_on=1, right_index=True, suffixes=("_origin", "_destination"))
)

# build a geopandas data frame that has LineString between two hospitals
gdf = gpd.GeoDataFrame(
    data=df,
    geometry=df.apply(
        lambda r: shapely.geometry.LineString(
            [(r["Longitude_origin"], r["Latitude_origin"]),
             (r["Longitude_destination"], r["Latitude_destination"]) ]), axis=1)
)

# sample code https://plotly.com/python/lines-on-mapbox/#lines-on-mapbox-maps-from-geopandas
lats = []
lons = []
names = []

for feature, name in zip(gdf.geometry, gdf["OrganisationName_origin"] + " - " + gdf["OrganisationName_destination"]):
    if isinstance(feature, shapely.geometry.linestring.LineString):
        linestrings = [feature]
    elif isinstance(feature, shapely.geometry.multilinestring.MultiLineString):
        linestrings = feature.geoms
    else:
        continue
    for linestring in linestrings:
        x, y = linestring.xy
        lats = np.append(lats, y)
        lons = np.append(lons, x)
        names = np.append(names, [name]*len(y))
        lats = np.append(lats, None)
        lons = np.append(lons, None)
        names = np.append(names, None)

fig = px.line_mapbox(lat=lats, lon=lons, hover_name=names)

fig.update_layout(mapbox_style="stamen-terrain",
                  mapbox_zoom=4,
                  mapbox_center_lon=gdf.total_bounds[[0,2]].mean(),
                  mapbox_center_lat=gdf.total_bounds[[1,3]].mean(),
                  margin={"r":0,"t":0,"l":0,"b":0}
                 )

简化版

  • 使用医院之间链接的数据框作为样本数据
  • plotly 文档和标签明确指出需要在传递给 px.line_mapbox() 的数组中用 None 分隔行。使用 numpy 以更直接的方式构建这些,无需构建 LineString,使用 geopnadasshapely
# plotly takes array delimited with None between lines. Use numpy padding and shaping to generate this array
# from pair of features
def line_array(df, cols):
    return np.pad(df.loc[:,cols].values, [(0, 0), (0, 1)], constant_values=None).reshape(1,(len(df)*3))[0]
    

fig = px.line_mapbox(lat=line_array(df, ["Latitude_origin", "Latitude_destination"]), 
                     lon=line_array(df, ["Longitude_origin", "Longitude_destination"]),
                     hover_name=line_array(df, ["OrganisationName_origin", "OrganisationName_destination"]),
)

fig.update_layout(mapbox_style="stamen-terrain",
                  mapbox_zoom=4,
                  mapbox_center_lon=df.loc[:,["Longitude_origin","Longitude_destination"]].mean().mean(),
                  mapbox_center_lat=df.loc[:,["Latitude_origin","Latitude_destination"]].mean().mean(),
                  margin={"r":0,"t":0,"l":0,"b":0}
                 )


enter image description here

关于python - 如何使用 Python 在 map 上绘制可视化线串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69290957/

相关文章:

python - ubuntu eric 没有模块 PyQt5.Qsci

python - 枚举 PySpark 中的连续相等值组

python - 从 GeoJSON 对象创建 GeoDataFrame

python - Geopandas:无法更改 geopandas 对象的 crs

python - 使用 OpenCV 进行视频处理

python - 如何在 Django 中创建继承自 AbstractUser 的多个 UserProfiles?

python - 退格键似乎在 python 中不起作用

python - 使用 pandas 读取 .csv 文件时指定时间戳短语格式?

python - groupby 和 sum by 指定 pandas 中的行类型

python - 在区域的部分区域添加边框,matplotlib/geopandas