如何使用Python绘制一行排列的多幅密度等高线子图
解决方案
seaborn的displot是图级接口,本身会独立创建画布,不支持传入外部坐标轴对象。你可以用两种方案实现1行3列的密度等高线子图,数据预处理部分和你现有代码完全一致,直接复用即可。
方案1:使用seaborn axes级接口sns.kdeplot
这是改动最小的方案,sns.kdeplot直接支持传入ax参数绑定到指定子图:
from astropy.table import Table, join import numpy as np import matplotlib.pyplot as plt import seaborn as sns import pandas as pd from scipy import stats # 以下数据清洗代码和你原有逻辑完全一致 RErange = Table.read('../../GAMA_Data/REMassEClassEmeasure.fits') RErange = RErange[RErange['SurfaceDensityFlag'] == 0] RErange = RErange[RErange['AGEDenParFlag'] == 0] RErange = RErange[RErange['CountInCylFlag'] == 0] RErange = RErange[RErange['uminusr']> 0.001] df = RErange.to_pandas() # 创建1行3列的画布 fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(18, 5)) # 按你的实际需求配置三个子图的x、y字段和标题,此处为示例 plot_config = [ ("logmstar", "uminusr", "子图1:恒星质量-色指数"), ("logmstar", "SurfaceDensity", "子图2:恒星质量-面密度"), ("logmstar", "CountInCyl", "子图3:恒星质量-柱内计数") ] for ax, (x_field, y_field, title) in zip(axes.flat, plot_config): # 绘制二维密度等高线,fill控制是否填充区域,cmap可自定义配色 sns.kdeplot(data=df, x=x_field, y=y_field, ax=ax, fill=True, cmap="viridis", levels=10) ax.set_title(title) ax.set_xlabel(x_field) ax.set_ylabel(y_field) # 自动调整子图间距 plt.tight_layout() plt.show()
方案2:不依赖seaborn,原生Matplotlib+Scipy实现
如果不想引入seaborn依赖,可以直接用Scipy计算核密度,再用Matplotlib绘制等高线:
from astropy.table import Table, join import numpy as np import matplotlib.pyplot as plt import pandas as pd from scipy.stats import gaussian_kde # 数据清洗逻辑和原有代码一致 RErange = Table.read('../../GAMA_Data/REMassEClassEmeasure.fits') RErange = RErange[RErange['SurfaceDensityFlag'] == 0] RErange = RErange[RErange['AGEDenParFlag'] == 0] RErange = RErange[RErange['CountInCylFlag'] == 0] RErange = RErange[RErange['uminusr']> 0.001] df = RErange.to_pandas() fig, axes = plt.subplots(1, 3, figsize=(18, 5)) plot_config = [ ("logmstar", "uminusr", "子图1:恒星质量-色指数"), ("logmstar", "SurfaceDensity", "子图2:恒星质量-面密度"), ("logmstar", "CountInCyl", "子图3:恒星质量-柱内计数") ] for ax, (x_field, y_field, title) in zip(axes.flat, plot_config): x = df[x_field].values y = df[y_field].values # 计算二维核密度 xy = np.vstack([x, y]) kde = gaussian_kde(xy) # 生成插值网格 xi, yi = np.mgrid[x.min():x.max():100j, y.min():y.max():100j] zi = kde(np.vstack([xi.flatten(), yi.flatten()])).reshape(xi.shape) # 绘制填充等高线+等高线边框 ax.contourf(xi, yi, zi, cmap="viridis", levels=10) ax.contour(xi, yi, zi, colors="white", linewidths=0.5, levels=10) ax.set_title(title) ax.set_xlabel(x_field) ax.set_ylabel(y_field) plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者Keith Sloan
相关产品推荐
相关产品推荐

