如何使用Python在底图中添加图例

时间:2018-07-29 21:53:33

标签: python python-2.7 matplotlib matplotlib-basemap

我正在尝试在世界地图上添加一个图例。每个点都是来自不同推文的不同类型的设备。 World map

这是我的代码:

def batchStoreTasks(tasks: List[Task]): Try[Task] = tasks match {
   case Nil => Failure(EmptyTaskListException)
   case x :: Nil => taskStorage(x)
   case x :: t => val storedTask = taskStorage(x); if(storedTask.isSuccess) batchStoreTasks(t) else storedTask

}

您有没有建议改善我的地图?不同的颜色,不同的地图? 我正在使用Pycharm的Python 2.7。我的样本数据是:

import geocoder
import json
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt

def openJSON(file, path):
    with open(path + file + '.json', 'r') as fp:
        data = json.load(fp)
        return data


def App_users(data):
    android_users = []
    iphone_users = []
    other_users = []

    #3 types of users: Android, Iphone and others:
    for a, b, c, d in data:
        if "Twitter for Android" in d:
            android_users.append([a, b])
        elif "Twitter for iPhone" in d:
            iphone_users.append([a, b])
        else:
            other_users.append([a, b])

    data = (android_users, iphone_users, other_users)
    return data


if __name__ == '__main__':

    posXY_add = []

    for d in data[0:50]:
        if d["user"]["location"] != None:
            g = geocoder.google(d["user"]["location"])
            if g.latlng != None:
                a = g.latlng + [g.address] + [str(d["source"])]
                posXY_add.append(a)

    data = App_users(posXY_add)

    map = Basemap(llcrnrlat=-70, urcrnrlat=70,
                    llcrnrlon=-180, urcrnrlon=180, epsg=3395)
    map.arcgisimage(service='ESRI_Imagery_World_2D', xpixels = 1500, verbose= True)

    colors = ['r', 'g', 'b']
    increment = 0

    for app in data:
        for item in app:
            if len(item) == 2:
                lat, lon = item[0], item[1]
                x, y = map(lon, lat)
                map.plot(x, y, colors[increment] + 'o')
        increment += 1


    plt.title("Geo-position Twitter Devices")
    plt.show()

2 个答案:

答案 0 :(得分:1)

传奇部分:这与将图例放入情节中的方式相同-只需将plt.legend()的参数为m.plot()调用label。因此,在您的情况下,它将是:

handle_dict = {
    "Andriod" : 0,
    "iPhone" : 0,
    "Other" : 0
}
colors = ['r', 'g', 'b']
increment = 0

for app in data:
    for item in app:
        if len(item) == 2:
            lat, lon = item[0], item[1]
            x, y = map(lon, lat)
            map.plot(x, y, colors[increment] + 'o', label = 
                handle_dict[type_phone] if handle_dict[type_phone] == 0
                else "_no-legend_")
            handle_dict[type_phone] += 1
    increment += 1

plt.legend()
plt.title("Geo-position Twitter Devices")
plt.show()

您还必须修改代码以标识要绘制的电话的类型(因此,变量type_phone)。

这是指向documentation的有关图例的链接,用于修改图例。

使地图更好: 就个人而言,我喜欢将map.shadedrelief()用于这些世界视图-它不像map.bluemarble()那样暗,您可以轻松地更好地看到这些点。实际上,这里不需要map.arcgisimage()参数,因为您拥有的是世界视图而不是放大视图-如果您使用内置函数,它将更快地生成地图。我还将在markeredgewidth上添加map.plot()参数,以使标记边缘宽度为零以外的值,因为现在您的点看起来就像它们与背景融合在一起。它将使您的点更加突兀。

哦-如果可以的话,还要花点时间升级到Python 3。

答案 1 :(得分:0)

我刚刚用技巧解决了这个问题。我的代码在“ a”上的迭代;这样,我就可以绘制类别的第一个标签。在代码中:

handles = [("Android",None), ("iPhone",None), ("Other devices",None)]
colors = ['r', 'g','b']
increment = 0
for app in data:
    a = 0
    for item in app:
        if len(item) == 2:
            lat, lon = item[0], item[1]
            x, y = map(lon, lat)
            map.plot(x, y, colors[increment] + 'o', alpha=0.8, markersize=0.1, label=handles[increment][a])
            a = 1
    increment += 1
plt.legend(loc='lower left', shadow=True)