无法绘制 GeoDataFrame 以显示同一区域随时间的变化

Can't plot GeoDataFrame to show change in the same area over time

我有一个包含 3 列的 geopandas.geodataframe.GeoDataFrame:the_geom、属性 犯罪率,年份。请注意,这里的 the_geom 只是弗吉尼亚州的一个多边形。我想展示这种犯罪率随时间的变化。这是我目前拥有的:

sns.set_style("white")
fig, axs = plt.subplots(nrows=3, ncols=4, sharex=True, sharey=True, figsize=(10,5))
fig.tight_layout(pad=3.0)

i = 0
for year in range(1994, 2015, 2):
    subdf = c7[c7['Year']==year]

    divider = make_axes_locatable(axs[i//4, i%4])
    cax = divider.append_axes("right", size="5%", pad=0)
    axs[i//4, i%4].set_title(str(year))

    subdf.plot(ax=axs[i//4, i%4], 
           column='Property crime rate',
           cmap='RdBu_r',
           cax=cax,
           legend=True
          )
    axs[i//4, i%4].axis('off')
    i+=1

axs[i//4, i%4].axis('off')

问题是所有州都是相同的颜色,因为它们在右边的图例使用不同的比例。我希望它们都共享相同的比例,这样您就可以看到颜色随时间的变化。 sns.FacetGrid() 之类的东西似乎可以工作,但我无法让它与 GeoDataFrames 一起工作。当我在下面使用 plt.plot 时,它不显示多边形:

g = sns.FacetGrid(c7, col="Year", hue="Property crime rate")
g = (g.map(plt.plot, "Property crime rate").add_legend()) 

当我尝试用 gpd.GeoDataFrame.plot 替换 plt.plot 时,出现以下错误:

g = sns.FacetGrid(c7, col="Year", hue="Property crime rate")
g = (g.map(gpd.GeoDataFrame.plot, "Property crime rate").add_legend())

AttributeError: 'Series' object has no attribute 'geometry'

有人能帮忙吗?

您每年都在独立地绘制其他年份,因此该函数每次只是将一种颜色分配给一个值。要在子图之间共享颜色图,最简单的选择是在 subdf.plot 内指定整体最小值和最大值。 (我只是在这里猜测最优值。)

subdf.plot(ax=axs[i//4, i%4], 
           column='Property crime rate',
           cmap='RdBu_r',
           cax=cax,
           legend=True,
           vmin=1700,
           vmax=4100
          )

好吧,我经过大量修改后找到了解决方案。我没有尝试@martinfleis vmin 和 vmax,所以这也可能有效。我放弃了 plt.legend() 并使用了 plt.colorbar(),这似乎很有效。

import matplotlib
import matplotlib.cm as cm #color mapping function
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
import seaborn as sns
%matplotlib inline

sns.set_style("white")

# c7 is my geodataframe
va = c7[c7.State=='Virginia'].sort_values(by='Year').copy(deep=True)
va.reset_index(drop=True, inplace=True)

minima = min(va["Property crime rate"])
maxima = max(va["Property crime rate"])
norm = matplotlib.colors.Normalize(vmin=minima, vmax=maxima, clip=True)
mapper = cm.ScalarMappable(norm=norm, cmap=cm.cool)

fig, ax = plt.subplots(1, 1, figsize=(15,8))
ax.axis('off')

axinset1 = inset_axes(ax, loc='center right', borderpad=-7, # negative value borderpad pushes it out
                      width="2%", height="40%") # width/height = X% of parent_bbox width/height
cb = plt.colorbar(cax=axinset1, mappable=mapper)
cb.set_label("Property Crime Rate", labelpad=20)
fig.suptitle('Virginia\'s Property Crime Rate Over Time', y=1, fontsize=20) # y<1 brings down, y>1 brings up

for idx, row in va.iterrows():
    ax = fig.add_subplot(3, 4, idx+1)
    ax.set_title("{}".format(row.Year))
    va[va.Year == row.Year].plot(ax=ax, color=mapper.to_rgba(row["Property crime rate"]))
    ax.axis('off')
ax.axis('off')
plt.show()

产生: