pandas 如何在Map上绘制可视化线串

hgc7kmma  于 2023-05-21  发布在  其他
关注(0)|答案(2)|浏览(128)

我有一些Lng和lat的坐标,我把它们组合成一个Linestring。
线串由两个点组成。从一个点starting=origin和从一个点ending = destination
这是Linestring列的代码
erg2['Linestring'] = erg2.apply(lambda x: LineString([(x['latitude_origin'], x['longitude_origin']), (x['latitude_destination'], x['longitude_destination'])]), axis = 1)
我正在尝试所有方法来绘制从原点到目的地的Linestring,但没有任何好的结果。
你会帮我很多!
这是带有lng和lat的dataframe erg2以及组合的Linestrings...我怎么能把它们画在Map上。起点和终点列中的数字是城市的位置ID。
作为一个有经验的程序员,你会怎么做?两个点的散点还是组合的Linestrings??下面我将输入我的dataframe.head()。
通常df有[19600行x8列]
| 起源|目的地|移动|经度原点|纬度原点|
| --------------|--------------|--------------|--------------|--------------|
| 八十八|八十八|二十|13.481016| 52.457055|
| 八十八|八九|0| 13.481016| 52.457055|
| 八十八|一百一十|0| 13.481016| 52.457055|
| 八十八|一一一|0| 13.481016| 52.457055|
| 八十八|一百一十二|0| 13.481016| 52.457055|
| 八十七|八十三|0| 13.479667| 52.479600|
| 经度目的地|纬度目的地|线串|
| --------------|--------------|--------------|
| 13.481016| 52.457055| LINESTRING(52.45705489204205 13.4810161067992...|
| 13.504075| 52.443923| LINESTRING(52.45705489204205 13.4810161067992...|
| 13.613772| 52.533194| LINESTRING(52.45705489204205 13.4810161067992...|
| 13.586891| 52.523562| LINESTRING(52.45705489204205 13.4810161067992...|
| 13.559341| 52.507418| LINESTRING(52.45705489204205 13.4810161067992...|
| 13.481016| 52.457055| LINESTRING(52.45705489204205 13.4810161067992...|
我正在尝试使用来自@RobRaymond的geopandas的示例代码绘制线条
结果显示的线条毫无意义。这是输出:

所有的行都有这个描述在悬停都开始于87-...在我的dataframe中,你可以看到我们有origin 88等。
根据运动绘制线条也很重要。因为零运动不需要被标绘…我真的希望我把问题说清楚了。这真的有点超出了我的头。

efzxgjgh

efzxgjgh1#

  • 设置一些数据,这些数据是点之间的线。使用了5家随机的英国医院
  • 在 * 原点 * 和 * 目标 * 之间创建了LineString几何
  • 使用https://plotly.com/python/lines-on-mapbox/#lines-on-mapbox-maps-from-geopandas示例来显示使用LineString作为几何图形的工作原理与示例相同
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}
                 )

简化版

  • 使用医院之间的链接的 Dataframe 作为样本数据
    *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}
                 )

qlzsbp2j

qlzsbp2j2#

使用来自官方plotly参考的示例和数据,我已经替换了您的问题,并确定了阻止线段绘制的问题。您需要指定一列文本,以指示要设置颜色的组。因此,将颜色设置为数据中的组键列。

import plotly.express as px
import pandas as pd

df_airports = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2011_february_us_airport_traffic.csv')
df_airports.head()

df_flight_paths = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2011_february_aa_flight_paths.csv')
df_flight_paths.sort_values('cnt', ascending=False, inplace=True)

df_flight_paths = df_flight_paths.query("airport2 in ['DFW','LAX']")

df_flight_paths.head()
start_lat   start_lon   end_lat     end_lon     airline     airport1    airport2    cnt
33  33.942536   -118.408074     32.895951   -97.0372    AA  LAX     DFW     914
50  29.533694   -98.469778  32.895951   -97.0372    AA  SAT     DFW     826
44  41.979595   -87.904464  32.895951   -97.0372    AA  ORD     DFW     825
20  30.194533   -97.669872  32.895951   -97.0372    AA  AUS     DFW     820
19  33.640444   -84.426944  32.895951   -97.0372    AA  ATL     DFW     580

fig = px.line_mapbox(df_flight_paths,
                     lat="start_lat", 
                     lon="start_lon", 
                     color="airport2",
                     hover_name="airport1",
                     #animation_frame="time",
                     center =dict(lon=-97.0,lat=38.0),
                     zoom=3, height=600
                    )

fig.update_layout(mapbox_style="stamen-terrain",
                  mapbox_zoom=4,
                  mapbox_center_lon=-97.0,
                  mapbox_center_lat=38.0,
                  margin={"r":0,"t":0,"l":0,"b":0}
                 )

fig.show()

相关问题