在上一篇文章中我们详细学习了geoplot中较为基础的三种绘图API:pointplot()、polyplot()以及webmap(),而本文将会承接上文的内容,对geoplot中较为实用的几种高级绘图API进行介绍。
图1本文是基于geopandas的空间数据分析系列文章的第7篇,通过本文你将学习geoplot中的高级绘图API。
2 geoplot进阶上一篇文章中的pointplot()、polyplot以及webmap()帮助我们解决了在绘制散点、基础面以及添加在线地图底图的问题,为了制作出信息量更丰富的可视化作品,我们需要更强的操纵矢量数据与映射值的能力,geoplot为我们封装好了几种常见的高级可视化API。
2.1 ChoroplethChoropleth图又称作地区分布图或面量图,我们在系列之前的深入浅出分层设色篇中介绍过其原理及geopandas实现,可以通过将指标值映射到面数据上,以实现对指标值地区分布的可视化。
在geoplot中我们可以通过choropleth()来快速绘制地区分布图,其主要参数如下:
df:传入对应的GeoDataFrame对象
projection:用于指定投影坐标系,传入geoplot.crs中的对象
hue:传入对应df中指定列名或外部序列数据,用于映射面的颜色,默认为None即不进行设色
cmap:和matplotlib中的cmap使用方式一致,用于控制色彩映射方案
alpha:控制全局色彩透明度
scheme:作用类似geopandas中的scheme参数,用于控制分层设色,详见本系列文章的分层设色篇,但不同的是在geoplot0.4.0版本之后此参数不再搭配分层数量k共同使用,而是更新为传入mapclassify分段结果对象,下文中会做具体演示
legend:bool型,用于控制是否显示图例
legend_values:list型,用于自定义图例显示的各个具体数值
legend_labels:list型,用于自定义图例显示的各个具体数值对应的文字标签,与legend_values搭配使用
legend_kwargs:字典,在legend参数设置为True时来传入更多微调图例属性的参数
extent:元组型,用于传入左下角和右上角经纬度信息来设置地图空间范围,格式为(min_longitude, min_latitude, max_longitude, max_latitude)
figsize:元组型,用于控制画幅大小,格式为(x, y)
ax:matplotlib坐标轴对象,如果需要在同一个坐标轴内叠加多个图层就需要用这个参数传入先前待叠加的ax
hatch:控制填充阴影纹路,详情见本系列文章前作基础可视化篇图7
edgecolor:控制多边形轮廓颜色
linewidth:控制多边形轮廓线型
下面我们通过实际的例子来学习geoplot.choropleth的用法,这里使用到的数据为美国新型冠状肺炎各州病例数分布,对应日期为2020年5月14日,来自Github仓库:https://github.com/CSSEGISandData/COVID-19/tree/master/csse_covid_19_data/csse_covid_19_daily_reports_us;使用到的美国本土各州矢量面数据contiguous-usa.geojson已上传到文章开头对应的Github仓库中:
图2 图3首先我们将两张表中各自对应的州名数据作为键进行连接(注意pd.merge返回的结果类型为DataFrame,需要转换回GeoDataFrame):
# 按照州名列进行连接 usa_plot_base = pd.merge(left=contiguous_usa, right=usa_covid19_20200513, left_on='state', right_on='Province_State') # 转换DataFrame到GeoDataFrame,注意要加上crs信息 usa_plot_base = gpd.GeoDataFrame(usa_plot_base, crs='EPSG:4326')接下来我们将确诊数作为映射值,因为美国各州中纽约州和新泽西州确诊数量分别达到了34万和14万,远远超过其他州,所以这里作为单独的图层进行阴影填充以突出其严重程度:
# 图层1:除最严重两州之外的其他州 ax = gplt.choropleth(df=usa_plot_base.query("state not in ['New York', 'New Jersey']"), projection=gcrs.AlbersEqualArea(), hue='Confirmed', scheme=mc.FisherJenks(usa_plot_base.query("state not in ['New York', 'New Jersey']")['Confirmed'], k=3), cmap='Reds', alpha=0.8, edgecolor='lightgrey', linewidth=0.2, figsize=(8, 8) ) # 图层2:纽约州 ax = gplt.polyplot(df=usa_plot_base.query("state == 'New York'"), hatch='/////', edgecolor='black', ax=ax) # 图层3:新泽西州 ax = gplt.polyplot(df=usa_plot_base.query("state == 'New Jersey'"), hatch='/////', edgecolor='red', extent=usa_plot_base.total_bounds, ax=ax) # 实例化cmap方案 cmap = plt.get_cmap('Reds') # 得到mapclassify中BoxPlot的数据分层点 bp = mc.FisherJenks(usa_plot_base.query("state not in ['New York', 'New Jersey']")['Confirmed'], k=3) bins = [0] + bp.bins.tolist() # 制作图例映射对象列表,这里分配Greys方案到三种色彩时对应的是[0, 0.5, 1]这三个采样点 LegendElement = [mpatches.Patch(facecolor=cmap(_ / 2), label=f'{int(bins[_])}-{int(bins[_+1])}') for _ in range(3)] + \ [mpatches.Patch(facecolor='none', edgecolor='black', linewidth=0.2, hatch='/////', label='New York: {}'.format(usa_plot_base.query("state == \"New York\"").Confirmed.to_list()[0])), mpatches.Patch(facecolor='none', edgecolor='red', linewidth=0.2, hatch='/////', label='New Jersey: {}'.format(usa_plot_base.query("state == \"New Jersey\"").Confirmed.to_list()[0]))] # 将制作好的图例映射对象列表导入legend()中,并配置相关参数 ax.legend(handles = LegendElement, loc='lower left', fontsize=8, title='确诊数量', title_fontsize=10, borderpad=0.6) # 添加标题 plt.title('美国新冠肺炎各州病例数(截至2020.05.14)', fontsize=18) # 保存图像 plt.savefig('图4.png', dpi=300, pad_inches=0, bbox_inches='tight') 图4