Полигоны меток GeoPandas

Учитывая, что файл формы доступен здесь: я хотел бы отметить каждый многоугольник (округ) на карте. Возможно ли это с помощью GeoPandas?

import geopandas as gpd
import matplotlib.pyplot as plt
%matplotlib inline

shpfile=<Path to unzipped .shp file referenced and linked above>
c=gpd.read_file(shpfile)
c=c.loc[c['GEOID'].isin(['26161','26093','26049','26091','26075','26125','26163','26099','26115','26065'])]
c.plot()

Заранее спасибо!


person Dance Party2    schedule 11.08.2016    source источник


Ответы (2)


c['geometry'] - это серия, состоящая из shapely.geometry.polygon.Polygon объектов. Вы можете убедиться в этом, проверив

In [23]: type(c.ix[23, 'geometry'])
Out[23]: shapely.geometry.polygon.Polygon

В Shapely docs есть метод _ 4_, которые

Возвращает дешево вычисленную точку, которая гарантированно находится внутри геометрического объекта.

Идеально подходит для ситуации, когда вам нужно пометить полигональные объекты! Затем вы можете создать новый столбец для своего geopandas dataframe, 'coords' вот так

c['coords'] = c['geometry'].apply(lambda x: x.representative_point().coords[:])
c['coords'] = [coords[0] for coords in c['coords']]

Теперь, когда у вас есть набор координат, относящихся к каждому объекту многоугольника (для каждого округа), вы можете аннотировать свой график, выполняя итерацию через фрейм данных.

c.plot()
for idx, row in c.iterrows():
    plt.annotate(s=row['NAME'], xy=row['coords'],
                 horizontalalignment='center')

введите описание изображения здесь

person lanery    schedule 11.08.2016
comment
@Фантастика! Спасибо. - person Dance Party2; 11.08.2016
comment
Вместо annotate можно использовать text, что удобно, когда вы хотите сопоставить данные с фоном: ax.text(row.coords[0], row.coords[1], s=row[variable], horizontalalignment='center', bbox={'facecolor': 'white', 'alpha':0.8, 'pad': 2, 'edgecolor':'none'}) - person Martien Lubberink; 16.11.2019

нет необходимости в цикле, вот как вы можете аннотировать с помощью apply:

ax = df.plot()
df.apply(lambda x: ax.annotate(s=x.NAME, xy=x.geometry.centroid.coords[0], ha='center'),axis=1);
person tozCSS    schedule 13.02.2017
comment
Элегантно и просто. - person Dance Party2; 15.02.2017
comment
Вы допустили опечатку: xy=x.coords? - person dmvianna; 07.08.2017
comment
Принятый ответ сработал для меня, но не этот. В этом примере у меня есть два интересных столбца: name и geometry. Когда apply перебирает их, и, судя по распечаткам, он не получает данные строка за строкой, это больше похоже на столбец за столбцом. - person Hakim; 26.11.2017
comment
если кто-то приходит сюда и имеет те же метки, что и @ h4k1m - ›вам нужно установить x.geometry.centroid.coords [0] как xy, чтобы это решение работало - person Maik Ro; 27.02.2018
comment
Спасибо @Maik R. Я думаю, что мой код был изначально таким, как вы предложили. Но через некоторое время я почему-то подумал, что geometry не нужен, и отредактировал решение, чтобы сделать его более элегантным. Вместо этого я, видимо, сломал его. Спасибо за исправление. - person tozCSS; 27.02.2018
comment
если кто-то сталкивается с этой проблемой, которая x.name дает порядковые номера x['name'] - person till Kadabra; 16.02.2020