pandas boxplot中共享轴的不同ylim

spo*_*234 7 python matplotlib pandas

我有一个分组的熊猫箱图,安排在(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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我现在只想更改ylim第二行.

我的想法是添加:

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

要么

[ax_tmp.set_ylim(-10,10) for ax_tmp in np.asarray(bp)[1,:]]
Run Code Online (Sandbox Code Playgroud)

但他们都改变了所有子图的ylim.这可能是因为共享.但我不知道要摆脱它.

我的问题与这个问题有些相关:pandas boxplot,groupby在每个子图中不同的ylim,但在我看来并不重复.此解决方案也不容易适用.

更新:理想情况下,行应共享一个共同的y,而不是每个绘图都有自己的

Ken*_*ste 9

解决方案是将一个fig,axespandas 传递给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()
Run Code Online (Sandbox Code Playgroud)

结果:

在此输入图像描述

如果你想分享行.此代码适用于您:

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()
Run Code Online (Sandbox Code Playgroud)

正如您所看到的那样,仅使用all_axes[1][0].set_ylim(-2,2)整行更改第2行中第1轴的ylim .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)
Run Code Online (Sandbox Code Playgroud)

结果:

在此输入图像描述