Python 箱线图中每个子地块的独立轴

Python 箱线图中每个子地块的独立轴,python,pandas,dataframe,matplotlib,boxplot,Python,Pandas,Dataframe,Matplotlib,Boxplot,下面的代码有助于获得具有唯一彩色框的子图。但所有子地块共享一组共同的x轴和y轴。我希望每个子图都有独立的轴: import pandas as pd import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import PathPatch df = pd.DataFrame(np.random.rand(140, 4), columns=['A', 'B', 'C', 'D']) df['model

下面的代码有助于获得具有唯一彩色框的子图。但所有子地块共享一组共同的x轴和y轴。我希望每个子图都有独立的轴:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch

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_dict = df.boxplot(
by="models",layout=(2,2),figsize=(6,4),
return_type='both',
patch_artist = True,
)

colors = ['b', 'y', 'm', 'c', 'g', 'b', 'r', 'k', ]
for row_key, (ax,row) in bp_dict.iteritems():
    ax.set_xlabel('')
    for i,box in enumerate(row['boxes']):
        box.set_facecolor(colors[i])

plt.show()
以下是上述代码的输出:

我正在尝试为每个子地块分别设置x轴和y轴。。。

您可以将标签设置为再次可见,例如通过

plt.setp(ax.get_xticklabels(), visible=True)

虽然这并不能使轴独立,但它们仍然相互绑定,但您似乎在询问可见性,而不是此处的共享行为。

您需要先创建图形和子图,并将其作为参数传递给
df.boxplot()
。这也意味着您可以删除参数
layout=(2,2)

然后使用:

bp_dict = df.boxplot(
by="models", ax=axes, figsize=(6,4),
return_type='both',
patch_artist = True,
)

如果您确实认为有必要在创建
boxplot
数组后取消共享轴,则可以执行此操作,但必须“手动”完成所有操作。在stackoverflow中搜索一段时间并查看
matplotlib
文档页面,我想出了以下解决方案来取消共享
实例的
yaxes
,对于
xaxes
,您必须进行类似操作:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch
from matplotlib.ticker import AutoLocator, AutoMinorLocator

##using differently scaled data for the different random series:
df = pd.DataFrame(
    np.asarray([
        np.random.rand(140),
        2*np.random.rand(140),
        4*np.random.rand(140),
        8*np.random.rand(140),
    ]).T,
    columns=['A', 'B', 'C', 'D']
)

df['models'] = pd.Series(np.repeat([
    'model1','model2', 'model3', 'model4',   'model5', 'model6', 'model7'
], 20))

##creating the boxplot array:
bp_dict = df.boxplot(
    by="models",layout = (2,2),figsize=(6,8),
    return_type='both',
    patch_artist = True,
    rot = 45,
)

colors = ['b', 'y', 'm', 'c', 'g', 'b', 'r', 'k', ]

##adjusting the Axes instances to your needs
for row_key, (ax,row) in bp_dict.items():
    ax.set_xlabel('')

    ##removing shared axes:
    grouper = ax.get_shared_y_axes()
    shared_ys = [a for a in grouper]
    for ax_list in shared_ys:
        for ax2 in ax_list:
            grouper.remove(ax2)

    ##setting limits:
    ax.axis('auto')
    ax.relim()      #<-- maybe not necessary

    ##adjusting tick positions:
    ax.yaxis.set_major_locator(AutoLocator())
    ax.yaxis.set_minor_locator(AutoMinorLocator())

    ##making tick labels visible:    
    plt.setp(ax.get_yticklabels(), visible=True)

    for i,box in enumerate(row['boxes']):
        box.set_facecolor(colors[i])

plt.show()
将熊猫作为pd导入
将numpy作为np导入
将matplotlib.pyplot作为plt导入
从matplotlib.patches导入PathPatch
从matplotlib.ticker导入AutoLocator、AutoMinorLocator
##对不同的随机序列使用不同比例的数据:
df=pd.DataFrame(
np.asarray([
np.random.兰德(140),
2*np.随机兰特(140),
4*np.随机兰特(140),
8*np.随机兰特(140),
]).T,
列=['A','B','C','D']
)
df['models']=pd.系列(np.repeat([
“模型1”、“模型2”、“模型3”、“模型4”、“模型5”、“模型6”、“模型7”
], 20))
##创建箱线图阵列:
bp_dict=df.boxplot(
by=“models”,布局=(2,2),figsize=(6,8),
return_type='both',
patch_artist=True,
rot=45,
)
颜色=['b','y','m','c','g','b','r','k',]
##根据需要调整轴实例
对于bp_dict.items()中的行键(ax,row):
ax.集合标签(“”)
##删除共享轴:
grouper=ax.get_shared_y_axes()
shared_ys=[a代表石斑鱼中的a]
对于共享目录中的ax_列表:
对于ax_列表中的ax2:
石斑鱼。移除(ax2)
##设置限制:
轴(“自动”)

ax.relim()#谢谢你的回答..但我的意思是所有轴都有独立的范围(特别是yaxis,其中Ylim需要为每个子批次分开)。绑定范围限制了具有较低数据范围但较高轴范围的框的视图。在这种情况下,请参考另一个答案。感谢答案…将布局限制为plt。子地块要求网格框的数量等于所需的子地块。您能推荐一种相对简单的方法来容纳2xn布局中的13个子地块吗?如果我在df.boxplot中使用布局参数,那么轴将保持共享。。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch
from matplotlib.ticker import AutoLocator, AutoMinorLocator

##using differently scaled data for the different random series:
df = pd.DataFrame(
    np.asarray([
        np.random.rand(140),
        2*np.random.rand(140),
        4*np.random.rand(140),
        8*np.random.rand(140),
    ]).T,
    columns=['A', 'B', 'C', 'D']
)

df['models'] = pd.Series(np.repeat([
    'model1','model2', 'model3', 'model4',   'model5', 'model6', 'model7'
], 20))

##creating the boxplot array:
bp_dict = df.boxplot(
    by="models",layout = (2,2),figsize=(6,8),
    return_type='both',
    patch_artist = True,
    rot = 45,
)

colors = ['b', 'y', 'm', 'c', 'g', 'b', 'r', 'k', ]

##adjusting the Axes instances to your needs
for row_key, (ax,row) in bp_dict.items():
    ax.set_xlabel('')

    ##removing shared axes:
    grouper = ax.get_shared_y_axes()
    shared_ys = [a for a in grouper]
    for ax_list in shared_ys:
        for ax2 in ax_list:
            grouper.remove(ax2)

    ##setting limits:
    ax.axis('auto')
    ax.relim()      #<-- maybe not necessary

    ##adjusting tick positions:
    ax.yaxis.set_major_locator(AutoLocator())
    ax.yaxis.set_minor_locator(AutoMinorLocator())

    ##making tick labels visible:    
    plt.setp(ax.get_yticklabels(), visible=True)

    for i,box in enumerate(row['boxes']):
        box.set_facecolor(colors[i])

plt.show()