在地图上绘制不同大小的圆圈

时间:2015-04-09 12:31:22

标签: python pandas matplotlib matplotlib-basemap

我有以下排序 DataFrame(数字完全随机):

In[1]: df
Out[1]:
            Total  Count
Location 1     20      5
Location 2     15      4
Location 3     13      3
...
Location 10     1      1

每个位置都有纬度和经度。

我想使用圆圈在地图上绘制这些位置。圆的半径需要与Total中的数量相对应。换句话说,位置1需要有最大的圆圈,位置2需要较小的圆圈等等。

另外,我希望有颜色转换。红色的最大圆圈,橙色的下一个圆圈,黄色的下一个圆圈等等。

最后,我想在每个圆圈旁边做一个注释。

我设法在地图上绘制蓝点,但我不知道如何绘制具有相应大小和颜色的圆圈。

到目前为止,这是我的代码:

m = Basemap(resolution='i', projection='merc', llcrnrlat=49.0, urcrnrlat=52.0, llcrnrlon=1., urcrnrlon=8.0, lat_ts=51.0)
m.drawcountries()
m.drawcoastlines()
m.fillcontinents()

for row_index, row in df.iterrows():
    x, y = db.getLocation(row_index)
    lat, lon = m(y, x)
    m.plot(lat, lon, 'b.', alpha=0.5)
    #This draws blue dots.

plt.title('Top 10 Locations')
plt.show()

1 个答案:

答案 0 :(得分:2)

  • matplotlib scatter函数具有sc参数,可让您绘制不同大小和颜色的点。

    当您指定DataFrame.plot时,Pandas scatter方法会调用matplotlib kind='scatter'函数。它还将额外的参数传递给scatter的调用,因此您可以使用类似

    的内容
    df.plot(kind='scatter', x='lon', y='lat', s=df['Total']*50, c=df['Total'], cmap=cmap)
    

    绘制积分。

  • Annotating the points可以通过拨打plt.annotate来完成。

  • The gist_rainbow colormap从红色变为橙色变为黄色......变为紫色。 gist_rainbow_r是反转的色彩映射,使red对应最大值。


例如,

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'Total': [20,15,13,1],
                   'lat': [40,0,-30,50],
                   'lon': [40,50,60,70], }, 
                  index=['Location {}'.format(i) for i in range(1,5)])

cmap = plt.get_cmap('gist_rainbow_r')
df.plot(kind='scatter', x='lon', y='lat', s=df['Total']*50, c=df['Total'], cmap=cmap)

for idx, row in df.iterrows():
    x, y = row[['lon','lat']]
    plt.annotate(
        str(idx), 
        xy = (x, y), xytext = (-20, 20),
        textcoords = 'offset points', ha = 'right', va = 'bottom',
        bbox = dict(boxstyle = 'round,pad=0.5', fc = 'yellow', alpha = 0.5),
        arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0'))

plt.show()

产量

enter image description here


不要为每个点调用df.plotplt.scatter一次。随着点数的增加,这将变得非常缓慢。相反,在DataFrame中收集必要的数据(经度和纬度),以便可以使用一次调用绘制点到df.plot

longitudes, latitudes = [], []
for row_index, row in df.iterrows():
    x, y = db.getLocation(row_index)
    lat, lon = m(y, x)
    longitudes.append(lon)
    latitudes.append(lat)
    plt.annotate(
        str(row_index), 
        xy = (x, y), xytext = (-20, 20),
        textcoords = 'offset points', ha = 'right', va = 'bottom',
        bbox = dict(boxstyle = 'round,pad=0.5', fc = 'yellow', alpha = 0.5),
        arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0'))

df['lon'] = longitudes
df['lat'] = latitudes
cmap = plt.get_cmap('gist_rainbow_r')
ax = plt.gca()
df.plot(kind='scatter', x='lon', y='lat', s=df['Total']*50, c=df['Total'], 
        cmap=cmap, ax=ax)