【问题标题】:Unable to use scatter plot in Basemap无法在底图中使用散点图
【发布时间】:2017-07-31 11:22:08
【问题描述】:

我正在学习教程Visualization: Mapping Global Earthquake Activity 以更熟悉底图。

我要做的是在地图上的 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 参数,则不需要将纬度/经度转换为地图投影的额外步骤。

如果 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 对象作为 xy 参数传递给它。但是,此代码确实有效(不同之处在于额外的 tolist() 调用):

my_map.plot(df_loc.lon.tolist(), 
            df_loc.lat.tolist(), 
            'bo', 
            latlon=True)

【问题讨论】:

  • 对于第二部分,您是否错过了第二个命令中的tolist(),即my_map.plot(df_loc.lon.tolist(), df_loc.lat.tolist(), 'bo', latlon=True)
  • @ThomasKühn 确实这似乎有效。我会更新 OP
  • 对于第一部分,如果你尝试x,y = my_map(df_loc.lon.tolist(), df_loc.lat.tolist())然后plt.scatter(x, y, s=df_loc.id, alpha=.3)呢?
  • @ThomasKühn 唉,这给出了相同的结果(只是渲染的地图,而不是点)。
  • 好的,如果你忽略fillcontinents会怎样?

标签: python pandas matplotlib matplotlib-basemap


【解决方案1】:

这是zorder 的问题。具体来说,fillcontinents zorder 大于 scatter 点的 zorder,因此散点在大陆的填充下方(因此不可见)。

解决此问题的两种方法:

  1. 减少fillcontinents zorder:

    my_map.fillcontinents(color='coral', zorder=0)
    
  2. 增加scatter zorder:

    my_map.scatter(x, y, s=10, zorder=10)
    

【讨论】:

  • 准确!谢谢。
猜你喜欢
  • 1970-01-01
  • 2020-02-07
  • 1970-01-01
  • 2017-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多