Как добавить легенду в Basemap с помощью Python

1

Я пытаюсь поставить легенду на моей карте мира. Каждая точка - это разные устройства из другого твита. Изображение 174551

Вот мой код:

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()

Есть ли у вас предложения улучшить мою карту? Различные цвета, разные карты или еще? Я использую Python 2.7 от Pycharm. Мои данные:

([[21.8974003, 83.39496319999999], [40.2671941, -86.1349019], [10.4805937, -66.90360629999999]], [[50.719164, -1.880769], [37.0903748, -94.5134078], [44.9862701, -93.39398279999999], [47.6062095, -122.3320708], [-27.4697707, 153.0251235], [20.593684, 78.96288]], [[43.2648545, -79.9492978], [39.1767262, -94.4867155], [33.7489954, -84.3879824], [39.7392358, -104.990251], [38.8761634, -77.0337777], [41.0082376, 28.9783589], [36.0753128, -95.95646269999999], [36.0595387, -95.90582429999999], [29.7604267, -95.3698028], [21.3014947, 106.6291304], [21.3014947, 106.6291304], [-16.6868982, -49.2648114], [10.4805937, -66.90360629999999], [45.037149, -92.825929], [33.760818, -78.967556], [45.49340369999999, -73.82329179999999], [39.750545, 37.0150217]])
Теги:
matplotlib
python-2.7
matplotlib-basemap

2 ответа

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).

Здесь ссылка на документацию относительно легенд, чтобы изменить легенду.

Создание карты лучше: Лично мне нравится использовать map.shadedrelief() для этих мировоззрений - она не map.bluemarble() темная, как map.bluemarble() и вы можете легко увидеть точки лучше. Здесь действительно нет необходимости в аргументе map.arcgisimage() потому что у вас есть представление о мире, а не увеличенное изображение - он будет генерировать вашу карту немного быстрее, если вы используете встроенную функцию. Я бы также добавить markeredgewidth аргумента map.plot(), чтобы сделать маркер шириной края, чтобы быть что - то отличное от нуля, потому что прямо сейчас ваши очки выглядят, как они сливаясь с фоном. Это заставит ваши точки выскакивать больше.

Ох - также возьмите тайм-аут, чтобы перейти на Python 3, если сможете.

  • 0
    Спасибо за ваш ответ, я ценю. К сожалению, проблема не была решена, потому что я часто визуализирую ярлык в легенде. Так что у меня на легенде много красных точек с «Android». Я не могу показать только три ярлыка.
  • 1
    Ах, недосмотр с моей стороны. Я пошел дальше и отредактировал пост, включив в него label = handle_dict[type_phone] if handle_dict[type_phone] == 0 else "_no-legend_" в map.plot() и добавил в словарь.
Показать ещё 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)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню