2016-10-20 1 views
3

У меня есть сгруппированные панды boxplot, устроить в (2,2) сетках:разных ylim для общих осей в панд boxplot

import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt 
df = pd.DataFrame(np.random.rand(140, 4), columns=['A', 'B', 'C', 'D']) 
df['models'] = pd.Series(np.repeat(['model1','model2', 'model3', 'model4', 'model5', 'model6', 'model7'], 20)) 
bp = df.boxplot(by="models",layout=(2,2),figsize=(6,8)) 
plt.show() 

enter image description here

Теперь я хочу, чтобы изменить ylim в секунде только строка.

Моя идея состояла в том, чтобы добавить:

[ax_tmp.set_ylim(-10,10) for ax_tmp in np.asarray(bp).reshape(-1)[2:4]] 

или

[ax_tmp.set_ylim(-10,10) for ax_tmp in np.asarray(bp)[1,:]] 

, но они оба изменить ylim всех сюжетных. Это может быть из-за разделяемого. Но я не собираюсь избавляться от него.

моя проблема несколько связана с этим: pandas boxplot, groupby different ylim in each subplot, но не дубликат на мой взгляд. Кроме того, решение здесь нелегко.

UPDATE: В идеале, строки должны разделять общую у, не каждый участок свой собственный

ответ

5

Раствор чтобы пропускать fig,axes к панд игровая boxplot, которые настроены с sharey=False:

import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt 

df = pd.DataFrame(np.random.rand(140, 4), columns=['A', 'B', 'C', 'D']) 
df['models'] = pd.Series(np.repeat(['model1','model2', 'model3', 'model4', 'model5', 'model6', 'model7'], 20)) 
fig, ax_new = plt.subplots(2,2, sharey=False) 
bp = df.boxplot(by="models",ax=ax_new,layout=(2,2),figsize=(6,8)) 
[ax_tmp.set_xlabel('') for ax_tmp in ax_new.reshape(-1)] 
[ax_tmp.set_ylim(-2, 2) for ax_tmp in ax_new[1]] 
fig.suptitle('New title here') 
plt.show() 

результат:

enter image description here

Если вы хотите делиться поровну. Этот код работает для вас:

import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt 

df = pd.DataFrame(np.random.rand(140, 4), columns=['A', 'B', 'C', 'D']) 
df['models'] = pd.Series(np.repeat(['model1','model2', 'model3', 'model4', 'model5', 'model6', 'model7'], 20)) 
layout = [2,2] 
fig = plt.figure() 
all_axes = [] 
counter = 1 
for i in range(layout[0]): 
    tmp_row_axes = [] 
    for j in range(layout[1]): 
     if j!=0 : 
      exec "tmp_row_axes.append(fig.add_subplot(%d%d%d, sharey=tmp_row_axes[0]))"%(layout[0],layout[1],counter) 
     else: 
      exec "tmp_row_axes.append(fig.add_subplot(%d%d%d))" % (layout[0], layout[1], counter) 
     counter+=1 
    all_axes.append(tmp_row_axes) 
all_axes = np.array(all_axes) 
bp = df.boxplot(by="models",ax=np.array(all_axes),layout=(2,2),figsize=(6,8)) 
[ax_tmp.set_xlabel('') for ax_tmp in all_axes.reshape(-1)] 
all_axes[1][0].set_ylim(-2,2) 
fig.suptitle('New title here') 
plt.show() 

Как вы видите, путем изменения только ylim из 1-й осей в 2-м ряду, используя all_axes[1][0].set_ylim(-2,2) вся строка изменяется. all_axes[1][1].set_ylim(-2,2) будет делать то же самое, так как они имеют общую ось y.

enter image description here

Если вы хотите, чтобы ось х только в последней строке и этикетки у оси только в первом столбце, просто измените петлю на это:

for i in range(layout[0]): 
    tmp_row_axes = [] 
    for j in range(layout[1]): 
     if j!=0 : 
      exec "tmp_ax = fig.add_subplot(%d%d%d, sharey=tmp_row_axes[0])"%(layout[0],layout[1],counter) 
      tmp_ax.get_yaxis().set_visible(False) 
     else: 
      exec "tmp_ax=fig.add_subplot(%d%d%d)" % (layout[0], layout[1], counter) 
     if i!=layout[1]-1 : 
      tmp_ax.get_xaxis().set_visible(False) 
     tmp_row_axes.append(tmp_ax) 
     counter+=1 
    all_axes.append(tmp_row_axes) 

результат:

enter image description here

Смежные вопросы