使用PolyLine连接Geopandas标记点失败问题排查
问题:Geopandas实现标记点与来源点连线失败排查
数据表格
| Score | LATITUDE | LONGITUDE | Name | From | geometry | |
|---|---|---|---|---|---|---|
| 0 | 9 | 47.0989 | 6.81907 | a | a | POINT (6.81906939 47.09885642) |
| 1 | 4 | 47.0993 | 6.82133 | b | a | POINT (6.82133392 47.09932583) |
| 2 | 12 | 47.1006 | 6.82169 | c | a | POINT (6.821687 47.10058986) |
| 3 | 12 | 47.1006 | 6.821687 | d | f | POINT (6.821687 47.10058986) |
| 4 | 2 | 47.0985 | 6.81926 | e | b | POINT (6.81926344 47.09847967) |
| 5 | 4 | 47.0998 | 6.82126 | f | b | POINT (6.82126031 47.09980364) |
| 6 | 2 | 47.0993 | 6.82197 | g | b | POINT (6.82197033 47.09929947) |
表格包含Name(点名称)和From(来源点名称)列,需将每个标记点与其来源点用线连接,但两次尝试均失败,仅显示标记点无连线。
第一次尝试代码
df2 = pd.merge(df, df[["Name", "LATITUDE", "LONGITUDE"]], on="Name", how="left", suffixes=["_to", "_from"]) latlong_from = zip(df2["LATITUDE_from"], df2["LONGITUDE_from"]) latlong_to = zip(df2["LATITUDE_to"], df2["LONGITUDE_to"]) for _from, _to in zip(latlong_from, latlong_to): folium.PolyLine([[_from[0], _from[1]], [_to[0], _to[1]]]).add_to(m) m
更新后的尝试代码
from shapely.geometry import LineString df2 = pd.merge(df, df[["Name", "LATITUDE", "LONGITUDE"]], on="Name", how="left", suffixes=["_to", "_from"]) df2["from_geometry"] = geopandas.points_from_xy(df2["LONGITUDE_from"], df2["LATITUDE_from"]) df2['line'] = df2.apply(lambda row: LineString([row['from_geometry'], row['geometry']]), axis=1) #Create a linestring column gdf2 = geopandas.GeoDataFrame( df2, geometry=df2["line"]) gdf2.drop(["line", "from_geometry"], axis=1, inplace=True) gdf2.crs = "EPSG:4326" gdf2.explore(color="red")
目标
实现每个标记点与其对应来源点之间的连线可视化。
最小可复现示例(MWE)
import geopandas import pandas as pd dict_data = {'Score': {0: 9, 1: 4, 2: 12, 3: 12, 4: 2, 5: 4, 6: 2}, 'LATITUDE': {0: 47.09885642, 1: 47.09932583, 2: 47.10058986, 3: 47.10058986, 4: 47.09847967, 5: 47.09980364, 6: 47.09929947}, 'LONGITUDE': {0: 6.81906939, 1: 6.82133392, 2: 6.821687, 3: 6.821687, 4: 6.81926344, 5: 6.82126031, 6: 6.82197033}, 'Name': {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g'}, 'From': {0: 'a', 1: 'a', 2: 'a', 3: 'f', 4: 'b', 5: 'b', 6: 'b'}} df = pd.DataFrame(dict_data) gdf = geopandas.GeoDataFrame( df, geometry=geopandas.points_from_xy(df["LONGITUDE"], df["LATITUDE"])) gdf.crs = "EPSG:4326" m = gdf.explore( column="Name", tiles="CartoDB positron", cmap="Set1" )
排查思路
- 合并逻辑检查:当前代码用
Name作为合并键,导致每个点连接的是自身而非来源点,正确的合并键应该是用当前点的From列匹配来源点的Name列。 - LineString有效性验证:创建线对象后,通过
gdf2.geometry.is_valid检查是否存在无效几何,确认线对象是否正确生成。 - 图层叠加方式:如果需要在已有点图层的地图上添加连线,需将连线GeoDataFrame叠加到同一个地图对象
m上,而非单独调用explore()生成新地图。 - 坐标顺序验证:确认Shapely和folium的坐标顺序要求(是经纬度还是纬度经度),避免因坐标顺序错误导致连线不可见。
- 连线样式调整:尝试设置更大的线宽(如
line_width=3)或更醒目的颜色,排除因线体过细、颜色不明显导致的视觉错觉。
内容的提问来源于Stack Exchange,提问作者Marco_CH
相关产品推荐
相关产品推荐

