[PYTHON] Subplot에 여러 개의 Seaborn Jointplot을 그라인딩하는 방법
PYTHONSubplot에 여러 개의 Seaborn Jointplot을 그라인딩하는 방법
Seaborn Jointplot을 다중 열 서브 플로트에 배치하는 데 문제가 있습니다.
import pandas as pd
import seaborn as sns
df = pd.DataFrame({'C1': {'a': 1,'b': 15,'c': 9,'d': 7,'e': 2,'f': 2,'g': 6,'h': 5,'k': 5,'l': 8},
'C2': {'a': 6,'b': 18,'c': 13,'d': 8,'e': 6,'f': 6,'g': 8,'h': 9,'k': 13,'l': 15}})
fig = plt.figure();
ax1 = fig.add_subplot(121);
ax2 = fig.add_subplot(122);
sns.jointplot("C1", "C2", data=df, kind='reg', ax=ax1)
sns.jointplot("C1", "C2", data=df, kind='kde', ax=ax2)
조인트 플롯의 일부분 만이 서브 플롯 내부에 배치되고 나머지는 다른 두 플롯 프레임 안에 어떻게 남겨져 있는지 주목하십시오. 내가 원하는 것은 두 분포를 서브 플로트 안에 삽입하는 것입니다.
아무도 이것으로 도울 수 있습니까?
해결법
-
==============================
1.해킹 없이는 쉽게 할 수 없습니다. jointplot은 JointGrid 메서드를 호출합니다.이 메서드는 호출 될 때마다 새 Figure 개체를 만듭니다.
해킹 없이는 쉽게 할 수 없습니다. jointplot은 JointGrid 메서드를 호출합니다.이 메서드는 호출 될 때마다 새 Figure 개체를 만듭니다.
따라서 해킹은 두 개의 조인트 플롯 (JG1 JG2)을 만든 다음 새 그림을 만든 다음 JG1 JG2에서 생성 된 새 그림으로 축 객체를 마이그레이션하는 것입니다.
마지막으로, 방금 만든 새 그림에서 하위 그림의 크기와 위치를 조정합니다.
JG1 = sns.jointplot("C1", "C2", data=df, kind='reg') JG2 = sns.jointplot("C1", "C2", data=df, kind='kde') #subplots migration f = plt.figure() for J in [JG1, JG2]: for A in J.fig.axes: f._axstack.add(f._make_key(A), A) #subplots size adjustment f.axes[0].set_position([0.05, 0.05, 0.4, 0.4]) f.axes[1].set_position([0.05, 0.45, 0.4, 0.05]) f.axes[2].set_position([0.45, 0.05, 0.05, 0.4]) f.axes[3].set_position([0.55, 0.05, 0.4, 0.4]) f.axes[4].set_position([0.55, 0.45, 0.4, 0.05]) f.axes[5].set_position([0.95, 0.05, 0.05, 0.4])
현재는 _axstack 및 _add_key private 메소드를 사용하고 있기 때문에 해킹입니다. matplotlib의 향후 버전과 동일하거나 동일하지 않을 수도 있습니다.
-
==============================
2.이전 버전에서 사용했던 것처럼 matplotlib에서 축을 이동하는 것은 쉽지 않습니다. 아래는 현재 버전의 matplotlib로 작업하고 있습니다.
이전 버전에서 사용했던 것처럼 matplotlib에서 축을 이동하는 것은 쉽지 않습니다. 아래는 현재 버전의 matplotlib로 작업하고 있습니다.
여러 장소 (이 질문,이 문제도)에서 지적 되었 듯이, 여러 가지 해상 지휘 명령은 자동으로 자신의 형상을 생성합니다. 이것은 해상 코드에 하드 코드되어 있으므로 현재는 기존 그림에 그러한 플롯을 생성 할 방법이 없습니다. PairGrid, FacetGrid, JointGrid, pairplot, jointplot 및 lmplot입니다.
플롯이 기존 그림에 생성되도록 각 클래스에 서브 플롯 그리드를 제공 할 수있는 해상 포크 (seaborn fork)가 있습니다. 이것을 사용하려면 포크에서 seaborn 폴더로 axisgrid.py를 복사해야합니다. 이것은 현재 matplotlib 2.1 (2.0도 가능)과 함께 사용하도록 제한되어 있습니다.
다른 방법으로는 해골 그림을 만들고 축을 다른 그림으로 복사하는 것입니다. 이것의 원리는이 답변에 나와 있으며 Searborn 구획으로 확장 될 수 있습니다. 구현은 처음에 예상했던 것보다 조금 더 복잡합니다. 다음은 seaborn 그리드 인스턴스 (위 명령 중 하나의 반환), matplotlib 그림 및 gridspec 그리드의 위치 인 subplot_spec으로 호출 할 수있는 SeabornFig2Grid 클래스입니다.
import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec import seaborn as sns import numpy as np class 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 matplotlib.pyplot as plt import matplotlib.gridspec as gridspec import seaborn as sns; sns.set() import SeabornFig2Grid as sfg iris = sns.load_dataset("iris") tips = sns.load_dataset("tips") # An lmplot g0 = sns.lmplot(x="total_bill", y="tip", hue="smoker", data=tips, palette=dict(Yes="g", No="m")) # A PairGrid g1 = sns.PairGrid(iris, hue="species") g1.map(plt.scatter, s=5) # A FacetGrid g2 = sns.FacetGrid(tips, col="time", hue="smoker") g2.map(plt.scatter, "total_bill", "tip", edgecolor="w") # A JointGrid g3 = sns.jointplot("sepal_width", "petal_length", data=iris, kind="kde", space=0, color="g") fig = plt.figure(figsize=(13,8)) gs = gridspec.GridSpec(2, 2) mg0 = sfg.SeabornFig2Grid(g0, fig, gs[0]) mg1 = sfg.SeabornFig2Grid(g1, fig, gs[1]) mg2 = sfg.SeabornFig2Grid(g2, fig, gs[3]) mg3 = sfg.SeabornFig2Grid(g3, fig, gs[2]) gs.tight_layout(fig) #gs.update(top=0.7) plt.show()
축 복사에서 몇 가지 단점이있을 수 있으며 위의 테스트는 철저히 테스트되지 않았습니다.
from https://stackoverflow.com/questions/35042255/how-to-plot-multiple-seaborn-jointplot-in-subplot by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 왜 속성 참조가 파이썬 상속과 같은 역할을합니까? [복제] (0) | 2018.10.05 |
---|---|
[PYTHON] 처음부터 발전기가 비어 있는지 어떻게 알 수 있습니까? (0) | 2018.10.05 |
[PYTHON] 파이썬에서 문자열을 정수로 분리하는 방법은? (0) | 2018.10.04 |
[PYTHON] Python을 사용하여 Windows에서 폴더 권한 설정 (0) | 2018.10.04 |
[PYTHON] 파이썬에서 문자열로부터 모듈로드하기 (0) | 2018.10.04 |