为何plt.figure(figsize)无法按预期放大2×2子图?
嘿,我来帮你搞清楚为什么你的绘图尺寸设置没生效~
核心问题所在
你的代码里的问题其实很直观:你是在创建好子图画布之后才调用plt.figure(),这时候它生成的是一个全新的空白画布,和你用来画4张子图的那个画布完全没关系。
具体拆解一下:
- 当你执行
fig, ax = plt.subplots(nrows=2, ncols=2)时,Matplotlib已经按照rcParams里的默认尺寸创建了一个画布(就是那个fig对象),同时生成了对应的2×2子图轴。 - 之后的
plt.figure(figsize=2 * np.array(plt.rcParams['figure.figsize']))是重新创建了一个独立的新画布,这个画布根本没被用来绘图——你后续所有的散点图都是画在第一个fig的子图上的,最后plt.show()显示的也是第一个画布,所以你设置的放大尺寸完全没作用在目标图上。
两种快速修正方案
方案1:创建子图时直接指定尺寸
最省心的方式,在调用plt.subplots()的时候就把figsize参数传进去,这样一开始就生成你想要的大尺寸画布:
import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.cluster import KMeans %config InlineBackend.figure_format = 'svg' # 用SVG提升画质 don = pd.read_csv('https://raw.githubusercontent.com/leanhdung1994/Deep-Learning/main/donclassif.txt.gz', sep=';') # 这里直接设置figsize,沿用你原来的放大逻辑 fig, ax = plt.subplots(nrows=2, ncols=2, figsize=2 * np.array(plt.rcParams['figure.figsize'])) for row in ax: for col in row: kmeans = KMeans(n_clusters=4) kmeans.fit(don) y_kmeans = kmeans.predict(don) col.scatter(don['V1'], don['V2'], c=y_kmeans, cmap='viridis') centers = kmeans.cluster_centers_ col.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.5); plt.show()
方案2:修改已创建画布的尺寸
如果你已经创建了fig对象,也可以通过set_size_inches()方法直接修改它的尺寸:
import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.cluster import KMeans %config InlineBackend.figure_format = 'svg' don = pd.read_csv('https://raw.githubusercontent.com/leanhdung1994/Deep-Learning/main/donclassif.txt.gz', sep=';') fig, ax = plt.subplots(nrows=2, ncols=2) # 修改已有画布的尺寸 fig.set_size_inches(2 * np.array(plt.rcParams['figure.figsize'])) for row in ax: for col in row: kmeans = KMeans(n_clusters=4) kmeans.fit(don) y_kmeans = kmeans.predict(don) col.scatter(don['V1'], don['V2'], c=y_kmeans, cmap='viridis') centers = kmeans.cluster_centers_ col.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.5); plt.show()
额外优化小建议
顺便提一句:你的代码里每次循环都重新训练一遍KMeans,其实完全没必要——因为数据是固定的,重复训练不仅浪费时间,还可能因为KMeans的随机初始化导致子图的聚类结果略有差异。可以把训练步骤提到循环外面,还能加上random_state保证结果稳定:
# 把KMeans训练移到循环外 kmeans = KMeans(n_clusters=4, random_state=42) # random_state固定随机种子 kmeans.fit(don) y_kmeans = kmeans.predict(don) centers = kmeans.cluster_centers_ for row in ax: for col in row: col.scatter(don['V1'], don['V2'], c=y_kmeans, cmap='viridis') col.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.5);
内容的提问来源于stack exchange,提问作者Akira
相关产品推荐
相关产品推荐

