sns.scatterplot绘制DBSCAN聚类散点图尺寸报错问题求解
DBSCAN聚类散点图画布尺寸报错解决方案
问题复现
针对含pos_x、pos_y特征的数据集,编写DBSCAN聚类结果散点图绘制代码如下:
colors=['purple','red','blue','green'] Data = [] dataset = pd.read_csv(r'/Users/file_name.csv') Datadb = dataset[["pos_x","pos_y"]] dbscan=DBSCAN() clusters =dbscan.fit(Datadb.to_numpy()) p = sns.scatterplot(data=Datadb, x="pos_x", y="pos_y", hue=clusters.labels_, legend="full", palette="deep") sns.move_legend(p, "upper right", bbox_to_anchor=(1.17, 1.2), title='Clusters') plt.show()
运行过程中依次遇到以下报错:
- 首次运行抛出尺寸超限错误:
ValueError: Image size of 447x412817 pixels is too large. It must be less than 2^16 in each direction. - 尝试给
sns.scatterplot传入height=4.27, aspect=5.7/4.27参数设置尺寸时,提示该接口不存在这两个参数 - 尝试通过返回对象调用
p.fig.set_figwidth()、p.fig.set_figheight()设置尺寸时,抛出属性错误:AttributeError: 'AxesSubplot' object has no attribute 'fig'
报错根因
sns.scatterplot属于seaborn的轴级函数,仅负责在现有matplotlib轴对象上绘图,本身不提供height、aspect这类画布尺寸控制参数,这类参数仅relplot、displot等seaborn图级函数支持。sns.scatterplot返回值是matplotlib的AxesSubplot对象,获取其绑定的画布对象需要用.figure属性,不存在.fig属性,因此调用时报错。- 初始代码没有提前指定画布尺寸,大数据量场景下seaborn自动推算的画布高度超过了matplotlib单方向最大像素限制(65536像素),触发尺寸超限错误。
- 初始代码中定义的
colors列表、空Data列表全程未被调用,属于冗余代码,可以直接删除减少内存占用。
解决方法
方法1:提前初始化固定尺寸画布(推荐,大数据量场景最稳定)
在调用绘图接口前,先通过matplotlib创建指定尺寸的画布,从根源避免自动尺寸推算错误,同时可以通过调小点尺寸加快渲染:
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from sklearn.cluster import DBSCAN # 提前设置画布尺寸,单位为英寸,dpi固定为100,按需求调整宽高数值即可 plt.figure(figsize=(6.27, 7.7), dpi=100) dataset = pd.read_csv(r'/Users/file_name.csv') Datadb = dataset[["pos_x", "pos_y"]] dbscan = DBSCAN() clusters = dbscan.fit(Datadb.to_numpy()) p = sns.scatterplot( data=Datadb, x="pos_x", y="pos_y", hue=clusters.labels_, legend="full", palette="deep", s=5 # 大数据量下把点大小调小,避免重叠同时大幅提升渲染速度 ) sns.move_legend(p, "upper right", bbox_to_anchor=(1.17, 1.2), title='Clusters') plt.tight_layout() # 自动调整布局,避免坐标轴、图例被截断 plt.show()
方法2:换用seaborn图级函数relplot绘制
如果习惯直接在seaborn接口内传参控制尺寸,可以使用支持height、aspect参数的relplot绘制散点图(散点是relplot的默认图类型):
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from sklearn.cluster import DBSCAN dataset = pd.read_csv(r'/Users/file_name.csv') Datadb = dataset[["pos_x", "pos_y"]] dbscan = DBSCAN() clusters = dbscan.fit(Datadb.to_numpy()) # relplot为图级函数,直接支持尺寸参数 g = sns.relplot( data=Datadb, x="pos_x", y="pos_y", hue=clusters.labels_, legend="full", palette="deep", height=7.7, # 画布高度,单位英寸 aspect=6.27/7.7, # 宽高比,实际宽度=height*aspect s=5 ) sns.move_legend(g, "upper right", bbox_to_anchor=(1.17, 1.2), title='Clusters') plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者ttina
相关产品推荐
相关产品推荐

