Python 3.x 正确重用GeoDataFrame.plot()中的轴

Python 3.x 正确重用GeoDataFrame.plot()中的轴,python-3.x,pandas,matplotlib,geopandas,Python 3.x,Pandas,Matplotlib,Geopandas,我想画一张简单的纽约choropleth地图,上面有黄色出租车。我的gpd.DataFrame如下所示: bin cnt shape 0 15 1 POLYGON ((-74.25559 40.62194, -74.24448 40.621... 1 16 1 POLYGON ((-74.25559 40.63033, -74.24448 40.630... 2 25

我想画一张简单的纽约choropleth地图,上面有黄色出租车。我的gpd.DataFrame如下所示:

   bin  cnt                                              shape
0   15    1  POLYGON ((-74.25559 40.62194, -74.24448 40.621...
1   16    1  POLYGON ((-74.25559 40.63033, -74.24448 40.630...
2   25    1  POLYGON ((-74.25559 40.70582, -74.24448 40.705...
3   27    1  POLYGON ((-74.25559 40.72260, -74.24448 40.722...
4   32   12  POLYGON ((-74.25559 40.76454, -74.24448 40.764...
其中,
bin
是一个区域数,
cnt
是我绘图的目标变量,
shape
列只是一系列
shapely
矩形,组成一个覆盖整个纽约的矩形

从shapefile绘制NYC:

usa = gpd.read_file('shapefiles/gadm36_USA_2.shp')[['NAME_1', 'NAME_2', 'geometry']]
nyc = usa[usa.NAME_1 == 'New York']
ax = plt.axes([0, 0, 2, 2], projection=ccrs.PlateCarree())
ax.set_extent([-74.25559, -73.70001, 40.49612, 40.91553], ccrs.Geodetic())    
ax.add_geometries(nyc.geometry.values, 
                  ccrs.PlateCarree(),
                  facecolor='#1A237E');

仅绘制choropleth就可以很好地工作:

gdf.plot(column='cnt', 
         cmap='inferno', 
         scheme='natural_breaks', k=10, 
         legend=True)

但是如果我把
ax
参数

gdf.plot(ax=ax, ...)
输出是

<Figure size 432x288 with 0 Axes>

仅使用来自geopandas的
调用执行此操作时,这似乎工作正常。因为我没有你的数据,所以我不得不编造一些数据。让我知道这是否有帮助。代码示例应该像在IPython中一样工作

%matplotlib inline
import geopandas as gpd
import numpy as np
from shapely.geometry import Polygon
from random import random

crs = {'init': 'epsg:4326'}
num_squares = 10

# load natural earth shapes

world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))

# create random choropleth

minx, miny, maxx, maxy = world.geometry.total_bounds

x_coords = np.linspace(minx, maxx, num_squares+1)
y_coords = np.linspace(miny, maxy, num_squares+1)

polygons = [Polygon([[x_coords[i], y_coords[j]],
                     [x_coords[i+1], y_coords[j]],
                     [x_coords[i+1], y_coords[j+1]],
                     [x_coords[i], y_coords[j+1]]]) for i in 
range(num_squares) for j in range(num_squares)]

vals = [random() for i in range(num_squares) for j in range(num_squares)]

choro_gdf = gpd.GeoDataFrame({'cnt' : vals, 'geometry' : polygons})
choro_gdf.crs = crs

# now plot both together

ax = choro_gdf.plot(column='cnt', 
                    cmap='inferno', 
                    scheme='natural_breaks', k=10, 
                    #legend=True
                    )

world.plot(ax=ax)
这应该会给你以下的东西

--编辑,如果您担心设置正确的限制(就像您对自治区所做的那样),请将以下内容粘贴到代码末尾(例如)

这样,您就可以:


在调用
gdf.plot(ax=ax,…)
之前,图形和轴对象是否仍然存在?另外,如果使用
fig,ax=plt.subplot(subplot_kw={'projection':ccrs.PlateCarree()})定义轴,它会改变什么吗?难道不可能只通过geopandas调用来绘制所有的东西吗,比如在这里()?1)axes对象肯定存在2)添加plt。子图没有什么区别3)问题是我的数据被计算到合成矩形箱中,而不是实际的纽约市计数还有两件事。为什么在调用的末尾有一个半列
ax.add_geometry(nyc.geometry.values,ccrs.PlateCarree(),facecolor='#1A237E')?如果您将此调用的结果分配给变量,比如说
base
,并在
gdf.plot()
调用中使用
ax=base
,该怎么办?更新了我的答案以提供正确的工作代码,您的答案中唯一缺少的是错误的zorder
%matplotlib inline
import geopandas as gpd
import numpy as np
from shapely.geometry import Polygon
from random import random

crs = {'init': 'epsg:4326'}
num_squares = 10

# load natural earth shapes

world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))

# create random choropleth

minx, miny, maxx, maxy = world.geometry.total_bounds

x_coords = np.linspace(minx, maxx, num_squares+1)
y_coords = np.linspace(miny, maxy, num_squares+1)

polygons = [Polygon([[x_coords[i], y_coords[j]],
                     [x_coords[i+1], y_coords[j]],
                     [x_coords[i+1], y_coords[j+1]],
                     [x_coords[i], y_coords[j+1]]]) for i in 
range(num_squares) for j in range(num_squares)]

vals = [random() for i in range(num_squares) for j in range(num_squares)]

choro_gdf = gpd.GeoDataFrame({'cnt' : vals, 'geometry' : polygons})
choro_gdf.crs = crs

# now plot both together

ax = choro_gdf.plot(column='cnt', 
                    cmap='inferno', 
                    scheme='natural_breaks', k=10, 
                    #legend=True
                    )

world.plot(ax=ax)
ax.set_xlim(0, 50)
ax.set_ylim(0, 25)