我按照教程Visualization: Mapping Global Earthquake Activity来熟悉Basemap。
我想要做的是在地图上分散绘制Pandas DataFrame中的数据。
我的地图的初始化代码:
my_map = Basemap(projection='merc',
lat_0=50.93, lon_0=4.13,
llcrnrlat=49.339950, llcrnrlon=1.777668,
urcrnrlat=51.601360, urcrnrlon=6.925303,
resolution='h', area_thresh=1.0)
my_map.drawcoastlines()
my_map.drawcountries()
my_map.fillcontinents(color='coral')
my_map.drawmapboundary()
到目前为止一切顺利。现在为实际数据。我的df结构如下:
lat float64
lon float64
id int64
dtype: object
样品:
| | lat | lon | id |
|-----:|--------:|--------:|-----:|
| 1083 | 51.8205 | 4.62573 | 7 |
| 211 | 50.5155 | 3.89612 | 1 |
| 89 | 50.3397 | 4.61034 | 1 |
id
列实际上是一个计数(df是更详细的df的聚合)。 id
列中的值应用于定义标记大小。
我从这个简单的情节(不是散点图)开始,它有效。
x,y = my_map(df_loc.lon.tolist(), df_loc.lat.tolist())
my_map.plot(x, y, 'bo', markersize=10)
plt.show()
因为我希望标记大小取决于计数(即id
列),所以我需要从plot
切换到scatter
。
如果我尝试:my_map.scatter(x, y, s=10)
(即固定大小),结果将为空地图(不绘制任何点)。
如果你能告诉我我做错了什么,我将不胜感激。奇怪的是,常规散点图工作得很好(可能是一个糟糕的比较,但仍然):
plt.scatter(df_loc.lon, df_loc.lat, s=df_loc.id, alpha=.3)
plt.ylim(49.339950, 51.601360)
plt.xlim(1.777668, 6.925303)
额外信用:
根据我在文档中阅读的内容,如果指定了latlon=True
参数,则不需要将lat / lon转换为地图投影的附加步骤。
如果latlon关键字设置为True,则x,y表示为经度和 纬度(以度为单位)。数据和经度会自动转移到 匹配圆柱形和圆柱形的圆形投影区域 投影和x,y被转换为地图投影坐标。
但是,如果我改变了这个:
x,y = my_map(df_loc.lon.tolist(), df_loc.lat.tolist())
my_map.plot(x, y, 'bo', markersize=10)
到此:
my_map.plot(df_loc.lon, df_loc.lat, 'bo', latlon=True)
我最终得到了错误:
SystemError: <class 'RuntimeError'> returned a result with an error set
这不是latlon
参数应该用于什么?
更新
似乎plot
函数不希望将Pandas Series对象作为x
和y
参数传递给它。但是,此代码可以正常工作(差异是额外的tolist()
调用):
my_map.plot(df_loc.lon.tolist(),
df_loc.lat.tolist(),
'bo',
latlon=True)
答案 0 :(得分:2)
这是zorder
的问题。具体而言,fillcontinents
zorder大于scatter
点的zorder,因此散点将在大陆填充下方结束(因此不可见)。
解决此问题的两种方法:
减少fillcontinents
zorder:
my_map.fillcontinents(color='coral', zorder=0)
增加scatter
zorder:
my_map.scatter(x, y, s=10, zorder=10)