Я только что начал изучать библиотеку Geopandas на Python. У меня есть набор данных с Lat (E) и Lon (N) автомобильных аварий в Белграде.
Я хочу нанести эти точки на карту Белграда.
Это мой код:
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt
pd.set_option('display.max_rows', 150)
pd.set_option('display.max_columns', 200)
pd.set_option('display.width', 5000)
# reading csv into geopandas
geo_df = gpd.read_file('SaobracajBeograd.csv')
geo_df.columns = ["ID", "Date,Time", "E", "N", "Outcome", "Type", "Description", "geometry"]
geo_df.geometry = gpd.points_from_xy(geo_df.E, geo_df.N)
#print(geo_df)
# reading built in dataset for each city
world_cities = gpd.read_file(gpd.datasets.get_path('naturalearth_cities'))
# I want to plot geometry column only for Belgrade
ax = world_cities[world_cities.name == 'Belgrade'].plot(figsize=(7, 7), alpha=0.5, edgecolor='black')
geo_df.plot(ax=ax, color='red')
plt.show()
Это результат, который я получаю:
Как я могу украсить этот график, чтобы я мог видеть карту города (с улицами, если возможно, в цвете) и с более мелкими красными точками?
Можете ли вы показать мне, как это сделать?
где я могу найти эти данные? SaobracajBeograd.csv
вы можете скачать его здесь: sendspace.com/file/5p2hc8
Похоже, вы не можете получить карту города, используя набор данных из world_cities
.
Например, если вы проверите
belgrade = world_cities[world_cities.name == 'Belgrade']
он возвращает следующий фрейм данных geopandas
name geometry
102 Belgrade POINT (20.46604 44.82059)
geometry
имеет форму точки, которая в основном представляет собой долготу и широту. Геометрия должна включать какой-либо полигон, чтобы получить форму города, который вы хотите.
Например, если вы извлекаете страну из набора данных world
следующим образом:
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
serbia = world[world.name == "Serbia"]
он возвращает следующий фрейм данных geopandas для serbia
pop_est continent name iso_a3 gdp_md_est geometry
172 7111024 Europe Serbia SRB 101800.0 POLYGON ((18.82982 45.90887, 18.82984 45.90888...
Как видите, геометрия имеет форму многоугольника. Теперь вы можете построить карту, используя serbia.plot()
, чтобы получить карту Сербии, которая выглядит следующим образом:
Чтобы получить карту города, вам нужно сначала загрузить шейп-файл города в виде файла *.shp
вместе с другими вспомогательными файлами и прочитать файл *.shp
как gpd.read_file("file.shp")
. Только после этого вы сможете построить карту нужного города.
Не подскажете, где можно скачать файлы .shp?
Это может быть предоставлено национальными государственными учреждениями или статистикой. Я сделал быстрый поиск в Google, но не могу найти файл формы на уровне города. Довольно легко найти шейп-файлы на уровне страны.
Я смог найти шейп-файл Сербии на этом веб-сайте diva-gis.org/gdata Вы можете скачать шейп-файл административной области Сербии. Можете ли вы прочитать файл формы SRB_adm2.shp как serbia = gpd.read_file("SRB_adm/SRB_adm2.shp")? В одной из колонок может быть название города, но они на сербском языке, а я, к сожалению, сербский не понимаю. Надеюсь, это поможет!
Я могу скачать zip файл, потом когда я его разархивирую, у меня есть файл SRB_adm2.shp но я не могу его прочитать, он показывает ошибку. Я могу прочитать весь zip-файл, но тогда у меня нет городов
from pathlib import Path
import pandas as pd
import geopandas as gpd
import shapely
import folium
# downloaded data
df = pd.read_csv(
Path.home().joinpath("Downloads/SaobracajBeograd.csv"),
names=["ID", "Date,Time", "E", "N", "Outcome", "Type", "Description"],
)
# create geodataframe, NB CRS
geo_df = gpd.GeoDataFrame(
df, geometry=gpd.points_from_xy(df["E"], df["N"]), crs = "epsg:4386"
)
# couldn't find belgrade geometry, used osmnx and simplified geometry as a WKT string
belgrade_poly = shapely.wkt.loads(
"POLYGON ((20.2213764 44.9154621, 20.2252450 44.9070062, 20.2399466 44.9067193, 20.2525385 44.8939145, 20.2419942 44.8842235, 20.2610016 44.8826597, 20.2794675 44.8754192, 20.2858284 44.8447802, 20.2856918 44.8332410, 20.3257447 44.8342507, 20.3328068 44.8098272, 20.3367239 44.8080890, 20.3339619 44.8058144, 20.3353253 44.8011005, 20.3336310 44.8003791, 20.3360230 44.7898245, 20.3384687 44.7907875, 20.3405086 44.7859144, 20.3417344 44.7872272, 20.3474466 44.7713203, 20.3509860 44.7687822, 20.3398029 44.7558716, 20.3220093 44.7448572, 20.3160895 44.7387338, 20.3235092 44.7345531, 20.3359605 44.7308053, 20.3437350 44.7301552, 20.3450306 44.7243651, 20.3497410 44.7209764, 20.3521450 44.7143627, 20.3633795 44.7046060, 20.3830709 44.7030441, 20.3845248 44.7011631, 20.3847991 44.7032182, 20.3924066 44.7036702, 20.4038881 44.6984458, 20.4097684 44.6992834, 20.4129839 44.7024603, 20.4192098 44.7021308, 20.4217436 44.7034920, 20.4251744 44.6976337, 20.4279418 44.6980838, 20.4313251 44.6940680, 20.4358368 44.6933579, 20.4402665 44.6905161, 20.4452138 44.6910160, 20.4495428 44.6880459, 20.4539572 44.6888231, 20.4529809 44.6911331, 20.4550753 44.6919188, 20.4534174 44.6929137, 20.4571253 44.6957696, 20.4570013 44.7008391, 20.4614601 44.7027894, 20.4646634 44.7018970, 20.4674388 44.7050131, 20.4753542 44.7039532, 20.4760757 44.7050260, 20.4802055 44.7033479, 20.4867635 44.7061539, 20.4983359 44.7022445, 20.5049892 44.7021663, 20.5071809 44.7071295, 20.5027682 44.7154832, 20.5028502 44.7217294, 20.5001912 44.7225288, 20.5007294 44.7251513, 20.5093727 44.7271542, 20.5316662 44.7248060, 20.5385861 44.7270519, 20.5390058 44.7329843, 20.5483761 44.7280993, 20.5513810 44.7308508, 20.5510751 44.7340860, 20.5483958 44.7345580, 20.5503614 44.7352316, 20.5509440 44.7434333, 20.5416617 44.7521169, 20.5358563 44.7553171, 20.5348919 44.7609694, 20.5393015 44.7624855, 20.5449353 44.7698750, 20.5490005 44.7708792, 20.5488362 44.7733456, 20.5647717 44.7649237, 20.5711431 44.7707818, 20.5772388 44.7711074, 20.5798915 44.7727751, 20.5852472 44.7808647, 20.5817268 44.7826053, 20.5823183 44.7845765, 20.5792147 44.7843299, 20.5777701 44.7872565, 20.5744279 44.7854098, 20.5740215 44.7886805, 20.5693220 44.7911579, 20.5655386 44.7906451, 20.5635444 44.7921747, 20.5598333 44.7901679, 20.5536143 44.7898282, 20.5502434 44.7909478, 20.5435002 44.8022967, 20.5424780 44.8073064, 20.5474459 44.8103678, 20.5530335 44.8102412, 20.5652728 44.8188428, 20.5738545 44.8279189, 20.5724006 44.8315147, 20.5776931 44.8371416, 20.5765153 44.8378971, 20.5863097 44.8427122, 20.5826128 44.8462544, 20.5762290 44.8486489, 20.5825139 44.8520894, 20.5953933 44.8552493, 20.6206689 44.8543410, 20.6212821 44.8560293, 20.6173687 44.8574761, 20.5961883 44.8615803, 20.5928447 44.8609861, 20.5911876 44.8626994, 20.6019440 44.8670619, 20.6196285 44.8673213, 20.6232109 44.8693710, 20.6164092 44.8815202, 20.6152606 44.8895682, 20.5777643 44.8860527, 20.5311826 44.8712209, 20.5230234 44.8646244, 20.5226088 44.8685278, 20.5187616 44.8654899, 20.5197414 44.8694015, 20.5132944 44.8687179, 20.5076686 44.8735038, 20.5065584 44.8670548, 20.4991594 44.8719635, 20.4938631 44.8734651, 20.4821047 44.8723679, 20.4737899 44.8677144, 20.4661802 44.8592493, 20.4594505 44.8560945, 20.4600397 44.8546034, 20.4650988 44.8535738, 20.4600110 44.8491680, 20.4623204 44.8477906, 20.4603705 44.8445375, 20.4711373 44.8342913, 20.4706338 44.8317839, 20.4498025 44.8343946, 20.4244846 44.8431449, 20.4138827 44.8526577, 20.3912248 44.8598333, 20.3749815 44.8683583, 20.3617778 44.8791076, 20.3436922 44.9103973, 20.3390650 44.9117584, 20.3011288 44.9426876, 20.2946156 44.9402419, 20.2960052 44.9381397, 20.2746476 44.9304194, 20.2703905 44.9345682, 20.2213764 44.9154621))"
)
# plot belgrade city limits
m = gpd.GeoDataFrame(geometry=[belgrade_poly], crs = "epsg:4326").explore(name = "Belgrade", height=300, width=500)
# plot the points, just for demo purposes plot outcomes as different colors
m = geo_df.explore(m=m, column = "Outcome", cmap=["red","green","blue"], name = "points")
# add layer control so layers can be switched on / off
folium.LayerControl().add_to(m)
m
Получить белградскую геометрию
import osmnx as ox
gdf = ox.geocode_to_gdf({'city': 'Belgrade'})
Не могли бы вы рассказать мне, как вы нашли значения полигонов в belgrade_poly?
добавлено дополнительное обновление для ответа
попробуйте использовать
explore()
вместо сюжета. Он использует фолиум со встроенными базовыми картами.