matplotlib GeoPandas中的格式化/舍入数字图例标签

zpjtge22  于 2023-05-01  发布在  其他
关注(0)|答案(2)|浏览(169)

我正在寻找一种方法来格式化/轮的数字图例标签在这些Map中产生的.plot()功能GeoPandas。例如:

gdf.plot(column='pop2010', scheme='QUANTILES', k=4)

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

我希望图例标签为整数。

rekjcdws

rekjcdws1#

由于我最近遇到了同样的问题,并且在Stack Overflow或其他网站上似乎没有现成的解决方案,我想我会发布我采取的方法,以防它有用。
首先,使用geopandas世界Map绘制一个基本图:

# 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()

我使用的方法依赖于matplotlib.legend.Legend对象的get_texts()方法,然后迭代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()

这是一个非常“试错”的方法,所以如果有更好的方法,我不会感到惊讶。尽管如此,也许这会有所帮助。

vsikbqxv

vsikbqxv2#

方法一

根据geopandas的更新日志,从**版本0开始,您可以在legend_kwdspass a fmt。8.0(2020年6月24日)**设置图例标签的格式。例如,如果你不想使用小数点,你可以设置fmt='{:.0f}',就像用f字符串格式化数字一样。以下是分位数贴图的示例:

import matplotlib.pyplot as plt
import numpy as np
import mapclassify
import geopandas as gpd

gdf = gpd.read_file(
    gpd.datasets.get_path('naturalearth_lowres')
)
np.random.seed(0)
gdf = gdf.assign(
    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(fmt='{:.0f}', interval=True),
    ax=ax
)

这为我们提供:

方法二

事实上,GeoPandas使用PySal的mapclassify来计算和生成Map图例。对于上面的分位数Map(k=5),我们可以通过mapclassify中的.Quantiles()得到分类。

mapclassify.Quantiles(gdf.random_col, k=5)

函数返回一个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

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

array([ 91.51435701,  97.92957441, 103.83406507, 109.49954895,
       123.83144775])

因此,我们可以使用这个函数来获得类的所有边界,因为较低类中的上限等于较高类中的下限。唯一缺少的是最低类中的下限,它等于您试图在DataFrame中分类的列的最小值。下面是一个将所有数字舍入为整数的示例:

# get all upper bounds
upper_bounds = mapclassify.Quantiles(gdf.random_col, k=5).bins
# insert minimal value in front to get all bounds
bounds = np.insert(upper_bounds, 0, gdf.random_col.min())
# format the numerical legend here
intervals = [
    f'{bounds[i]:.0f}-{bounds[i+1]:.0f}' for i in range(len(bounds)-1)
]

# get all the legend labels
legend_labels = ax.get_legend().get_texts()
# replace the legend labels
for interval, legend_label in zip(intervals, legend_labels):
    legend_label.set_text(interval)

我们最终会得到:

正如您所看到的,由于我们在较低的级别上执行操作,因此我们能够自定义图例标签的外观,例如删除那些括号,但在中间使用-

方法三

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

import geopandas as gpd
import geoplot as gplt

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

legend_labels = [
    '< 2.4', '2.4 - 6', '6 - 15', '15 - 38', '38 - 140 M'
]
gplt.choropleth(
    gdf, hue='pop_est', cmap='Blues', scheme='quantiles',
    legend=True, legend_labels=legend_labels
)

也就是说

相关问题