python - 如何在 Subplot 中绘制带有注释的多个 Seaborn Jointplot

标签 python plot seaborn subplot

目标是为带有相关注释的联合图创建子图。但是,当 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()

结果如下: enter image description here

这就是你要找的吗?

关于python - 如何在 Subplot 中绘制带有注释的多个 Seaborn Jointplot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70257063/

相关文章:

plot - 如何在 ILNumerics 中有效地绘制大表面(例如 1000x1000)?

python - 如何为 Seaborn Facet Plot 添加标题

python - 与 seaborn 的 kdeplot 上的带宽混淆

python - 如何在 scikit TfidfVectorizer 中为专有名词赋予更多权重

python - 在 if 循环中添加到字典

python - 如何在 Windows 10 上安装适用于 python 2.7.3 的 pip?

python - 使用 css 选择器提取具有特定类的链接

python - 如何识别 matplotlib 中的图形线

matlab - 从 contourf 图中删除线条

python - Matplotlib 箱线图传单未显示