目标是为带有相关注释的联合图创建子图。但是,当 plt.show()
时,图形会单独显示。
我可以知道如何解决这个问题吗?
import numpy as np
import pandas as pd
import scipy.stats as stats
import seaborn as sns
import matplotlib.pyplot as plt
ncols=['ra','rb','a','b','c','d']
df=pd.DataFrame(np.random.rand(100,len(ncols)),columns=ncols)
nvars=['a','b','c','d']
rt=['a','b']
fig, axs = plt.subplots(len(rt),len(nvars))
for idx_rt, nrt in enumerate(rt):
for idx_var, nvar in enumerate(nvars):
g=sns.jointplot(data=df, y=nrt, x=nvar,kind = 'reg',ax=axs[idx_rt,idx_var])
r, p = stats.pearsonr(df[nrt], df[nvar])
g.ax_joint.annotate(f'$\\rho = {r:.3f}, p = {p:.3f}$',
xy=(0.1, 0.9), xycoords='axes fraction',
ha='left', va='center',
bbox={'boxstyle': 'round', 'fc': 'powderblue', 'ec': 'navy'})
plt.tight_layout()
plt.show()
最佳答案
在此基础上构建answer您应该通过组合自定义 SeabornFig2Grid
类和 matplotlib GridSpec
来获得成功。这是您的玩具示例:
首先定义SeabornFig2Grid类
SeabornFig2Grid() 类:
def __init__(self, seaborngrid, fig, subplot_spec): self.fig = fig self.sg = seaborngrid self.subplot = subplot_spec if isinstance(self.sg, sns.axisgrid.FacetGrid) or \ isinstance(self.sg, sns.axisgrid.PairGrid): self._movegrid() elif isinstance(self.sg, sns.axisgrid.JointGrid): self._movejointgrid() self._finalize() def _movegrid(self): """ Move PairGrid or Facetgrid """ self._resize() n = self.sg.axes.shape[0] m = self.sg.axes.shape[1] self.subgrid = gridspec.GridSpecFromSubplotSpec(n,m, subplot_spec=self.subplot) for i in range(n): for j in range(m): self._moveaxes(self.sg.axes[i,j], self.subgrid[i,j]) def _movejointgrid(self): """ Move Jointgrid """ h= self.sg.ax_joint.get_position().height h2= self.sg.ax_marg_x.get_position().height r = int(np.round(h/h2)) self._resize() self.subgrid = gridspec.GridSpecFromSubplotSpec(r+1,r+1, subplot_spec=self.subplot) self._moveaxes(self.sg.ax_joint, self.subgrid[1:, :-1]) self._moveaxes(self.sg.ax_marg_x, self.subgrid[0, :-1]) self._moveaxes(self.sg.ax_marg_y, self.subgrid[1:, -1]) def _moveaxes(self, ax, gs): #https://stackoverflow.com/a/46906599/4124317 ax.remove() ax.figure=self.fig self.fig.axes.append(ax) self.fig.add_axes(ax) ax._subplotspec = gs ax.set_position(gs.get_position(self.fig)) ax.set_subplotspec(gs) def _finalize(self): plt.close(self.sg.fig) self.fig.canvas.mpl_connect("resize_event", self._resize) self.fig.canvas.draw() def _resize(self, evt=None): self.sg.fig.set_size_inches(self.fig.get_size_inches())
然后在同一个网格中绘制绘图
import itertools
import matplotlib.gridspec as gridspec
# import seaborn as sns; sns.set()
import numpy as np
import pandas as pd
import scipy.stats as stats
import seaborn as sns
import matplotlib.pyplot as plt
ncols=['ra','rb','a','b','c','d']
df=pd.DataFrame(np.random.rand(100,len(ncols)),columns=ncols)
nvars=['a','b','c','d']
rt=['a','b']
# A JointGrid
fig = plt.figure(figsize=(13,8))
gs = gridspec.GridSpec(len(rt),len(nvars))
for i, idxs in enumerate(itertools.product(rt, nvars)):
nrt, nvar = idxs
g=sns.jointplot(data=df, y=nrt, x=nvar,kind = 'reg')#, space=0,ax=axs[idx_rt,idx_var])
r, p = stats.pearsonr(df[nrt], df[nvar])
g.ax_joint.annotate(f'$\\rho = {r:.3f}, p = {p:.3f}$',
xy=(0.1, 0.9), xycoords='axes fraction',
ha='left', va='center',
bbox={'boxstyle': 'round', 'fc': 'powderblue', 'ec': 'navy'})
mg = SeabornFig2Grid(g, fig, gs[i])
gs.tight_layout(fig)
#gs.update(top=0.7)
plt.show()
这就是你要找的吗?
关于python - 如何在 Subplot 中绘制带有注释的多个 Seaborn Jointplot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70257063/