如何让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
相关产品推荐
相关产品推荐

