2017-11-28 14 views
1

私が取り組んでいるものの最小限のコード。いくつかのパラメータは重複しているように見えるかもしれませんが、すべてを削除することはありませんでした。コメントアウトmultipart seabornプロットでmatplotlib gridspecを繰り返し挿入するにはどうすればいいですか?

すべてseabornプロット(g)でコードを実行する
import matplotlib 
import matplotlib.gridspec as gridspec 
matplotlib.use("macosx") 
import matplotlib.pyplot as plt 
import pandas as pd 
import seaborn as sns 

def plot_overlaid_2d_hist(data, 
          plot_axis_x, 
          plot_axis_y, 
          plot_axis_x_lab, 
          plot_axis_y_lab, 
          group_by = "group_name"): 

    # don't mind this for now 
    df = data 

    # Figure aspect 
    w, h = plt.figaspect(1) 
    fig = plt.figure(figsize = (w, h)) 

    # Count the number of groups to make plots for 
    n_groups = len(df.groupby(group_by)) 
    gs = gridspec.GridSpec(nrows = n_groups, ncols = 1) 
    subplot_id = 0 

    # Reshape data to make it work 
    for name, group in df.groupby(group_by, sort = False): 

     # Initialize subplot 
     fig.add_subplot(gs[subplot_id, 0]) 

     # Check if we get subplots with pyplot 
     if subplot_id == 0: 
      col = "red" 
     else: 
      col = "blue" 

     plt.plot(x, y, color = col) 


     # instantiate JointGrid 
     # g = sns.JointGrid(group[plot_axis_x], 
     #     group[plot_axis_y], 
     #     data = group, 
     #     space = 0, 
     #     xlim = (0, 1.2), 
     #     ylim = (0, 1)) 
     # 
     # # Fix labels 
     # g = g.set_axis_labels(xlabel = str(plot_axis_x_lab), 
     #     ylabel = str(plot_axis_y_lab)) 
     # 
     # # center scatter plot on top 
     # g = g.plot_joint(plt.scatter, 
     #    s = 0.5, 
     #    alpha = 1, 
     #    linewidth = 1) 
     # 
     # # marginals plot 
     # g = g.plot_marginals(sns.distplot, 
     #     kde = True, 
     #     kde_kws = dict(linewidth = 2, 
     #         alpha = 1, 
     #         bw = "Scott"), 
     #     hist_kws = dict(alpha = 1)) 


     # Next plot in row +1 
     subplot_id += 1 

    # Output 
    plt.tight_layout() # Attempts to fix alignment of subplot layout and axis titles 

    plt.show() 

# quick data to check if the plots end up where they should 
x = [0.5, 0.5, 0.4, 0.4] 
y = [0.6, 0.4, 0.3, 0.4] 
grp = ["a", "a", "b", "b"] 


df = pd.DataFrame({"x":x, 
        "y":y, 
        "grp": grp}) 

plot_overlaid_2d_hist(data = df, 
         group_by = "grp", 
         plot_axis_x_lab = "x", 
         plot_axis_y_lab = "x", 
         plot_axis_y = "x", 
         plot_axis_x = "x") 

は、それがネイティブpyplotのため正常に動作することを示しているが、私はマルチパートseabornプロットに追加するときに、彼らは別の人物に表示されます。私が望むのは、各2Dヒストグラムと余白と散布図に独自のグリッドスペックの行/列を設定することです。

+0

ドキュメントをお読みになりましたか? 'JointGrid'はそれ自身のFigureを作成します。もしそれが起こらないようにするには、 'JointGrid'を使わないでください。 – ImportanceOfBeingErnest

+0

私はそこに道があると思った。実際には、https://github.com/mwaskom/seaborn/issues/399があることが分かりますが、まだ正式ではありません。 –

+0

その解決策は海底のソースコードの変更に依存していることを確かめてください。それをやりたいのであれば、途中で遭遇する問題についてはもちろん質問することができます。 – ImportanceOfBeingErnest

答えて

1

hereの前にこの質問が既に聞かれているのを見て、この答えを古い質問に移動しました。私はここでそれを削除したいと思いますが、それは既に受け入れられているので、できません

いくつかの場所(this question、またthis issue)で指摘されているように、海軍のコマンドのいくつかは自動的に独自の図形を作成します。これは海底のコードにハードコードされているため、現在は既存の図にそのようなプロットを作成する方法はありません。それらは、PairGrid,FacetGrid,JointGrid,pairplot,jointplotおよびlmplotである。

seaborn fork availableがあり、プロットが既存の図で作成されるように、それぞれのクラスにサブプロットグリッドを供給することができます。これを使用するには、axisgrid.pyをフォークからseabornフォルダにコピーする必要があります。これは現在、matplotlib 2.1(おそらく2.0も同様)で使用するように制限されていることに注意してください。

シーボーンの図を作成し、軸を別の図にコピーする方法もあります。これの原理はthis answerに示されており、Searbornプロットに拡張することができます。実装は私が最初に期待していたより少し複雑です。以下は、シーボーングリッドインスタンス(上記のコマンドのいずれかの戻り値)、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() 

enter image description here

注(まだ)ないですが徹底的にテストされています。

関連する問題