如何解决Scattergeo中标记大小调整导致点位重叠的问题?
问题:Go.Scattergeo气泡地图中大气泡覆盖小气泡
我用go.scattergeo制作气泡地图,整体功能正常,但调整气泡大小(每个气泡对应一个数值)时,最大的气泡会完全覆盖最小的气泡。我试过另外两种注释掉的气泡大小设置,结果完全一致。调整颜色不影响点位显示,查了Plotly完整文档也没找到相关说明,求问哪里操作出错了?
数据集说明
使用的是添加了出发港口经纬度的泰坦尼克号数据集,以下是10行样本:
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Embarked | lon | lat |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | 0 | 22.0 | 1 | 0 | A/5 21171 | 7.25 | 0 | -1.406013 |
| 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th...) | 1 | 38.0 | 1 | 0 | PC 17599 | 71.2833 | 1 | -8.294143 |
| 2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | 1 | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.925 | 0 | -1.406013 |
| 3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | 1 | 35.0 | 1 | 0 | 113803 | 53.1 | 0 | -1.406013 |
| 4 | 5 | 0 | 3 | Allen, Mr. William Henry | 0 | 35.0 | 0 | 0 | 373450 | 8.05 | 0 | -1.406013 |
| 5 | 6 | 0 | 3 | Moran, Mr. James | 0 | 29.699118 | 0 | 0 | 330877 | 8.4583 | 2 | -1.612260 |
| 6 | 7 | 0 | 1 | McCarthy, Mr. Timothy J | 0 | 54.0 | 0 | 0 | 17463 | 51.8625 | 0 | -1.406013 |
| 7 | 8 | 0 | 3 | Palsson, Master. Gosta Leonard | 0 | 2.0 | 3 | 1 | 349909 | 21.075 | 0 | -1.406013 |
| 8 | 9 | 1 | 3 | Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg) | 1 | 27.0 | 0 | 2 | 347742 | 11.1333 | 0 | -1.406013 |
| 9 | 10 | 1 | 2 | Nasser, Mrs. Nicholas (Adele Achem) | 1 | 14.0 | 1 | 0 | 237736 | 30.0708 | 1 | -8.294143 |
数据预处理代码
df.replace({'Embarked':{'S':0, 'C':1, 'Q':2}}, inplace=True) df.loc[df['Embarked']==0, 'lon'] = '-1.406013' df.loc[df['Embarked']==1, 'lon'] = '-8.294143' df.loc[df['Embarked']==2, 'lon'] = '-1.612260' df.loc[df['Embarked']==0, 'lat'] = '50.896364' df.loc[df['Embarked']==1, 'lat'] = '51.850910' df.loc[df['Embarked']==2, 'lat'] = '49.648194'
气泡地图绘制代码
import plotly.graph_objects as go import numpy as np sizearray = np.asarray(df['lon'].value_counts()) fig = go.Figure(data=go.Scattergeo(lon = df['lon'],lat = df['lat'],mode = 'markers')) fig.update_layout( title = 'Shipping Ports',geo_scope='world',) fig.update_geos(fitbounds="locations") fig.update_traces(marker=dict(size=sizearray,sizemode='area',sizeref=2.*max(sizearray)/(40.**2),sizemin=4)) #fig.update_traces(marker_size=sizearray/5) #fig.update_traces(marker_size=df['lon'].value_counts()/5) fig.update_traces(marker=dict(color=['rgb(93, 164, 214)', 'rgb(255, 144, 14)','rgb(44, 160, 101)'])) fig.show()
解决方案
问题核心是重复绘制同港口的所有乘客点,以及气泡大小数组与数据点数量不匹配:
- 你当前传入
Scattergeo的是整个数据集的经纬度,等于给每个乘客都画了一个点,同一港口的点完全重叠;而sizearray只有3个元素(对应3个港口的乘客数),Plotly会循环复用这个数组,最终大数值的气泡覆盖了同港口的所有小点。 - 正确做法是先聚合数据,只保留每个港口的唯一经纬度和对应的乘客总数,再绘制气泡。
修改后的代码
import plotly.graph_objects as go import numpy as np # 聚合港口数据:按港口分组,获取唯一经纬度和乘客总数 port_data = df.groupby('Embarked').agg({ 'lon': 'first', 'lat': 'first', 'PassengerId': 'count' }).reset_index() # 将字符串类型的经纬度转为数值型(避免Plotly定位偏差) port_data['lon'] = port_data['lon'].astype(float) port_data['lat'] = port_data['lat'].astype(float) fig = go.Figure(data=go.Scattergeo( lon = port_data['lon'], lat = port_data['lat'], mode = 'markers', marker=dict( size=port_data['PassengerId'], # 直接用聚合后的乘客数作为气泡大小 sizemode='area', sizeref=2.*max(port_data['PassengerId'])/(40.**2), sizemin=4, color=['rgb(93, 164, 214)', 'rgb(255, 144, 14)','rgb(44, 160, 101)'] ) )) fig.update_layout( title = 'Shipping Ports', geo_scope='world', ) fig.update_geos(fitbounds="locations") fig.show()
关键修改点
- 聚合去重:用
groupby得到每个港口的唯一数据,避免重复绘制同一港口的大量点; - 修正数据类型:将字符串格式的经纬度转为数值型,确保Plotly定位准确;
- 匹配气泡大小:直接绑定聚合后的乘客总数到气泡大小,每个港口对应唯一的气泡尺寸。
修改后每个港口只会显示一个气泡,大小对应乘客数量,不会再出现覆盖问题。
内容的提问来源于stack exchange,提问作者LFerALs Fer
相关产品推荐
相关产品推荐

