различные ylim для общих осей в Pandas boxplot
у меня есть сгруппированные панды boxplot, расположить в сетке (2,2):
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()
теперь я хочу изменить 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,:]]
но они оба меняют Илим всех подзаголовков. Это может быть из-за sharedy. Но я понятия не имею, как от него избавиться.
моя проблема несколько связана с этим: панды boxplot, groupby разные ylim в каждом подзаголовке но не дубликат, на мой взгляд. Кроме того, решение не легко применимо здесь.
обновление: в идеале строки должны иметь общий y, а не каждый участок свой собственный
1 ответов
решение передать 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()
результат:
если вы хотите поделиться row-wise. Этот код работает для вас :
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.
если вы хотите ось x только в последней строке и метку оси y только в первом столбце, просто измените цикл на это:
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)
результат: