You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Geopandas绘图的色条独立于vmax参数?

问题描述

我用以下代码绘制带统计数据的世界地图:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as mplc
from mpl_toolkits.axes_grid1 import make_axes_locatable
import geopandas as gpd
import numpy as np  # 补充原代码遗漏的numpy导入

world = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))
world = world[world.name != "Antarctica"]

np.random.seed(123)
countries = world['name'].sample(75, replace=True).tolist()

data = pd.DataFrame({'country': countries, 'count': np.random.randint(0, 500, 75)})

merged_data = world.merge(data, left_on='name', right_on="country", how="left")

fig, ax = plt.subplots(figsize=(10, 6))

cmap = mplc.LinearSegmentedColormap.from_list("custom", ["r", "b"])

divider = make_axes_locatable(ax)
cax = divider.append_axes("bottom", size="4%", pad=0, aspect=10)

merged_data.plot(column='count', ax=ax, cax=cax, cmap=cmap, linewidth=0.5, legend=True, edgecolors="k", missing_kwds={'color': 'lightgrey'}, legend_kwds={'label': "Number of people", 'orientation': "horizontal"}, vmin=0, vmax=3000)

fig = ax.figure
cb_ax = fig.axes[1]
cb_ax.tick_params(labelsize=8.5, size=2.5, direction="in")

ax.set_axis_off()
plt.show()

原本色条外观正常(希望所有图表保持该样式),但修改vmax的数值后,色条会突然变得细长,不符合报告中图表样式统一的需求。

解决方法

核心思路是固定色条的物理尺寸,使其不受数值范围(vmax)影响,以下两种方案均可实现:

方案1:改用plt.colorbar固定缩放比例

放弃make_axes_locatable的色条轴创建方式,直接用plt.colorbar的shrink参数固定色条缩放比例:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as mplc
import geopandas as gpd
import numpy as np

world = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))
world = world[world.name != "Antarctica"]

np.random.seed(123)
countries = world['name'].sample(75, replace=True).tolist()
data = pd.DataFrame({'country': countries, 'count': np.random.randint(0, 500, 75)})
merged_data = world.merge(data, left_on='name', right_on="country", how="left")

fig, ax = plt.subplots(figsize=(10, 6))
cmap = mplc.LinearSegmentedColormap.from_list("custom", ["r", "b"])

# 先绘制地图,不指定cax
plot_obj = merged_data.plot(
    column='count', ax=ax, cmap=cmap, linewidth=0.5, legend=False,
    edgecolors="k", missing_kwds={'color': 'lightgrey'},
    vmin=0, vmax=你的目标数值
)

# 手动添加色条,用shrink固定缩放比例
cbar = plt.colorbar(
    plot_obj, ax=ax, orientation="horizontal", pad=0.05,
    shrink=0.8, label="Number of people"
)
cbar.ax.tick_params(labelsize=8.5, size=2.5, direction="in")

ax.set_axis_off()
plt.show()

只要所有图表保持相同的shrink值,色条宽度就会完全一致,与vmax无关。

方案2:移除aspect参数固定色条轴尺寸

如果坚持使用make_axes_locatable,只需去掉aspect=10参数,让色条轴根据布局自动适配固定物理尺寸:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as mplc
from mpl_toolkits.axes_grid1 import make_axes_locatable
import geopandas as gpd
import numpy as np

world = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))
world = world[world.name != "Antarctica"]

np.random.seed(123)
countries = world['name'].sample(75, replace=True).tolist()
data = pd.DataFrame({'country': countries, 'count': np.random.randint(0, 500, 75)})
merged_data = world.merge(data, left_on='name', right_on="country", how="left")

fig, ax = plt.subplots(figsize=(10, 6))
cmap = mplc.LinearSegmentedColormap.from_list("custom", ["r", "b"])

divider = make_axes_locatable(ax)
# 移除aspect参数,保留size控制色条高度
cax = divider.append_axes("bottom", size="4%", pad=0.05)

merged_data.plot(
    column='count', ax=ax, cax=cax, cmap=cmap, linewidth=0.5, legend=True,
    edgecolors="k", missing_kwds={'color': 'lightgrey'},
    legend_kwds={'label': "Number of people", 'orientation': "horizontal"},
    vmin=0, vmax=你的目标数值
)

cb_ax = fig.axes[1]
cb_ax.tick_params(labelsize=8.5, size=2.5, direction="in")

ax.set_axis_off()
plt.show()
问题根源

原代码中aspect=10是强制设置色条轴的宽高比,当vmax改变导致数值范围变化时,matplotlib会为了维持该比例,自动拉伸或压缩色条的物理尺寸,最终出现细长的异常样式。移除该参数或改用固定缩放比例的方式,就能让色条尺寸脱离数值范围的影响。

内容的提问来源于stack exchange,提问作者rekitsitats

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 17:22:22