熊猫箱图中每个子图的独立轴

时间:2018-06-21 14:32:00

标签: 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['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()

这是上面代码的输出: enter image description here

我正在尝试为每个子图分别设置x和y轴... enter image description here

3 个答案:

答案 0 :(得分:2)

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

fig, axes = plt.subplots(2,2,sharex=False,sharey=False)

然后使用:

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

如果您真的认为有必要在创建boxplot数组后取消共享 轴,则可以执行此操作,但是您必须“手动”完成所有操作。在stackoverflow中搜索了一会儿,并查看了matplotlib文档页面,我想到了以下解决方案,以取消共享yaxes实例中的Axes实例中的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() ,您将不得不类似地去:

Axes

结果图如下:

result of the above code

说明

您首先需要告诉每个yaxis实例,它不应该与任何其他Axis实例共享其Axes.get_shared_y_axes()This post使我了解如何进行操作-Axes返回一个Grouper object,其中包含对当前{{1}的所有其他Axes实例的引用}应该共享其xaxis。遍历这些实例并调用Grouper.remove会真正取消共享。

一旦取消共享yaxis,就需要调整y的限制和y的刻度。前者可以通过ax.axis('auto')ax.relim()来实现(不确定第二条命令是否必要)。可以通过将ax.yaxis.set_major_locator()ax.yaxis.set_minor_locator()与适当的Locators一起使用来调整刻度。最后,可以使用plt.setp(ax.get_yticklabels(), visible=True)see here)使刻度标签可见。

考虑到所有这些,@ DavidG的answer在我看来是更好的方法。