web-dev-qa-db-fra.com

Traquage d'une carte à l'aide de Geopandas et Matplotlib

J'ai de petits CSV qui ont 6 coordonnées de Birmingham Angleterre. J'ai lu le CSV avec pandas puis la transforma en Geopandas Dataframe changer mes colonnes de latitude et de longitude avec des points gallés. J'essaie maintenant de tracer mon géodataframe et tout ce que je peux voir sont les points. Comment Je reçois aussi la carte de Birmingham aussi bien? Une bonne source de documentation sur les Geopandas serait aussi fortement appréciée.

from shapely.geometry import Point
import geopandas as gpd
import pandas as pd

df = pd.read_csv('SiteLocation.csv')
df['Coordinates'] = list(Zip(df.LONG, df.LAT))
df['Coordinates'] = df['Coordinates'].apply(Point)
# Building the GeoDataframe 
geo_df = gpd.GeoDataFrame(df, geometry='Coordinates')
geo_df.plot()  
6
Herc01

Essayez df.unary_union . La fonction regroupera des points dans une seule géométrie. Jupyter Notebook peut le tracer

0
felytic

Voulez-vous simplement ajouter l'étui d'utilisation concernant le zoom de la page où le Basemap est mis à jour en fonction des nouvelles coordonnées xlim et ylim. Une solution que j'ai créée est:

  • Les premiers rappels définis sur le ax qui peut détecter xlim_changed Et ylim_changed
  • Une fois que les deux ont été détectés comme modifiés, obtenez le nouveau plot_area Appelant ax.get_xlim() et ax.get_ylim()
  • Puis effacer le ax et ré-tracer le Basemap et toute autre donnée

Exemple pour une carte du monde montrant les capitales. Vous remarquez que lorsque vous zoomez dans la résolution de la carte est en cours de mise à jour.

import geopandas as gpd
import matplotlib.pyplot as plt
import contextily as ctx


figsize = (12, 10)
osm_url = 'http://tile.stamen.com/terrain/{z}/{x}/{y}.png'
EPSG_OSM = 3857
EPSG_WGS84 = 4326

class MapTools:
    def __init__(self):
        self.cities = gpd.read_file(
            gpd.datasets.get_path('naturalearth_cities'))
        self.cities.crs = EPSG_WGS84
        self.cities = self.convert_to_osm(self.cities)

        self.fig, self.ax = plt.subplots(nrows=1, ncols=1, figsize=figsize)
        self.callbacks_connect()

        # get extent of the map for all cities
        self.cities.plot(ax=self.ax)
        self.plot_area = self.ax.axis()

    def convert_to_osm(self, df):
        return df.to_crs(epsg=EPSG_OSM)

    def callbacks_connect(self):
        self.zoomcallx = self.ax.callbacks.connect(
            'xlim_changed', self.on_limx_change)
        self.zoomcally = self.ax.callbacks.connect(
            'ylim_changed', self.on_limy_change)

        self.x_called = False
        self.y_called = False

    def callbacks_disconnect(self):
        self.ax.callbacks.disconnect(self.zoomcallx)
        self.ax.callbacks.disconnect(self.zoomcally)

    def on_limx_change(self, _):
        self.x_called = True
        if self.y_called:
            self.on_lim_change()

    def on_limy_change(self, _):
        self.y_called = True
        if self.x_called:
            self.on_lim_change()

    def on_lim_change(self):
        xlim = self.ax.get_xlim()
        ylim = self.ax.get_ylim()
        self.plot_area = (*xlim, *ylim)
        self.blit_map()

    def add_base_map_osm(self):
        if abs(self.plot_area[1] - self.plot_area[0]) < 100:
            zoom = 13

        else:
            zoom = 'auto'

        try:
            basemap, extent = ctx.bounds2img(
                self.plot_area[0], self.plot_area[2],
                self.plot_area[1], self.plot_area[3],
                zoom=zoom,
                url=osm_url,)
            self.ax.imshow(basemap, extent=extent, interpolation='bilinear')

        except Exception as e:
            print(f'unable to load map: {e}')

    def blit_map(self):
        self.ax.cla()
        self.callbacks_disconnect()
        cities = self.cities.cx[
            self.plot_area[0]:self.plot_area[1],
            self.plot_area[2]:self.plot_area[3]]
        cities.plot(ax=self.ax, color='red', markersize=3)

        print('*'*80)
        print(self.plot_area)
        print(f'{len(cities)} cities in plot area')

        self.add_base_map_osm()
        self.callbacks_connect()

    @staticmethod
    def show():
        plt.show()


def main():
    map_tools = MapTools()
    map_tools.show()

if __name__ == '__main__':
    main()

Exécute sur Linux Python3.8 avec les installations PIP suivantes

affine==2.3.0
attrs==19.3.0
autopep8==1.4.4
Cartopy==0.17.0
certifi==2019.11.28
chardet==3.0.4
Click==7.0
click-plugins==1.1.1
cligj==0.5.0
contextily==1.0rc2
cycler==0.10.0
descartes==1.1.0
Fiona==1.8.11
geographiclib==1.50
geopandas==0.6.2
geopy==1.20.0
idna==2.8
joblib==0.14.0
kiwisolver==1.1.0
matplotlib==3.1.2
mercantile==1.1.2
more-itertools==8.0.0
munch==2.5.0
numpy==1.17.4
packaging==19.2
pandas==0.25.3
Pillow==6.2.1
pluggy==0.13.1
py==1.8.0
pycodestyle==2.5.0
pyparsing==2.4.5
pyproj==2.4.1
pyshp==2.1.0
pytest==5.3.1
python-dateutil==2.8.1
pytz==2019.3
rasterio==1.1.1
requests==2.22.0
Rtree==0.9.1
Shapely==1.6.4.post2
six==1.13.0
snuggs==1.4.7
urllib3==1.25.7
wcwidth==0.1.7

Notez notamment l'exigence de contextily==1.0rc2

Sous Windows, j'utilise Conda (P3.7.3) et n'oubliez pas de définir les variables utilisateur:

GDAL c:\Users\<username>\Anaconda3\envs\<your environment>\Library\share\gdal

PROJLIB c:\Users\<username>\Anaconda3\envs\<your environment>\Library\share

0
Bruno Vermeulen