GeoPandas 中的格式/圆形数字图例标签

ste*_*ven 4 python matplotlib geopandas pysal

我正在寻找一种方法来格式化/舍入由.plot()GeoPandas 中的函数生成的那些地图中的数字图例标签。例如:

gdf.plot(column='pop2010', scheme='QUANTILES', k=4)
Run Code Online (Sandbox Code Playgroud)

这给了我一个带有许多小数位的图例:

在此处输入图片说明

我希望图例标签是整数。

Bre*_*dan 7

由于我最近遇到了同样的问题,而且 Stack Overflow 或其他网站上似乎没有现成的解决方案,我想我会发布我所采用的方法,以防万一。

首先,使用geopandas世界地图绘制基本图:

# load world data set    
world_orig = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
world = world_orig[(world_orig['pop_est'] > 0) & (world_orig['name'] != "Antarctica")].copy()
world['gdp_per_cap'] = world['gdp_md_est'] / world['pop_est']

# basic plot
fig = world.plot(column='pop_est', figsize=(12,8), scheme='fisher_jenks', 
                 cmap='YlGnBu', legend=True)
leg = fig.get_legend()
leg._loc = 3
plt.show()
Run Code Online (Sandbox Code Playgroud)

世界地图 v1

我使用的get_texts()方法依赖于matplotlib.legend.Legend对象的方法,然后迭代 中的项目leg.get_texts(),将文本元素拆分为上下边界,然后创建一个应用格式的新字符串并使用set_text()方法设置它。

# formatted legend
fig = world.plot(column='pop_est', figsize=(12,8), scheme='fisher_jenks', 
                 cmap='YlGnBu', legend=True)
leg = fig.get_legend()
leg._loc = 3

for lbl in leg.get_texts():
    label_text = lbl.get_text()
    lower = label_text.split()[0]
    upper = label_text.split()[2]
    new_text = f'{float(lower):,.0f} - {float(upper):,.0f}'
    lbl.set_text(new_text)

plt.show()
Run Code Online (Sandbox Code Playgroud)

这在很大程度上是一种“反复试验”的方法,因此如果有更好的方法,我不会感到惊讶。不过,也许这会有所帮助。

世界地图 v2


ste*_*ven 5

方法一:

GeoPandas 使用 PySal 的mapclassify。这是分位数映射 (k=5) 的示例。

import matplotlib.pyplot as plt
import numpy as np
import mapclassify   # 2.3.0
import geopandas as gpd   # 0.8.1

# load dataset
path = gpd.datasets.get_path('naturalearth_lowres')
gdf = gpd.read_file(path)
# generate a random column
np.random.seed(0)
gdf['random_col'] = np.random.normal(100, 10, len(gdf))

# plot quantiles map
fig, ax = plt.subplots(figsize=(10, 10))
gdf.plot(column='random_col', scheme='quantiles', k=5, cmap='Blues',
         legend=True, legend_kwds=dict(loc=6), ax=ax)
Run Code Online (Sandbox Code Playgroud)

这给了我们:

在此处输入图片说明

假设我们要四舍五入图例中的数字。我们可以通过 中的.Quantiles()函数得到分类mapclassify

mapclassify.Quantiles(gdf.random_col, k=5)
Run Code Online (Sandbox Code Playgroud)

该函数返回一个对象mapclassify.classifiers.Quantiles

Quantiles               

    Interval       Count
------------------------
[ 74.47,  91.51] |    36
( 91.51,  97.93] |    35
( 97.93, 103.83] |    35
(103.83, 109.50] |    35
(109.50, 123.83] |    36
Run Code Online (Sandbox Code Playgroud)

该对象有一个属性bins,它返回一个包含所有类的上限的数组。

array([ 91.51435701,  97.92957441, 103.83406507, 109.49954895,
       123.83144775])
Run Code Online (Sandbox Code Playgroud)

因此,我们可以使用此函数来获取所有类的边界,因为较低类的上限等于较高类的下限。唯一缺少的是最低类中的下限,它等于您尝试在 DataFrame 中分类的列的最小值。

这是将所有数字四舍五入为整数的示例:

Quantiles               

    Interval       Count
------------------------
[ 74.47,  91.51] |    36
( 91.51,  97.93] |    35
( 97.93, 103.83] |    35
(103.83, 109.50] |    35
(109.50, 123.83] |    36
Run Code Online (Sandbox Code Playgroud)

我们最终会得到: 在此处输入图片说明


方法二:

除了 GeoPandas 的.plot()方法之外,您还可以考虑geoplot.choropleth()提供的功能,您可以在其中轻松使用不同类型的方案和类数,同时传递arg 来修改图例标签。例如,legend_labels

array([ 91.51435701,  97.92957441, 103.83406507, 109.49954895,
       123.83144775])
Run Code Online (Sandbox Code Playgroud)

这给了你

在此处输入图片说明