在子图中绘制Pandas箱线图的问题

5

我在子图中绘制Pandas箱线图时遇到了问题。根据我尝试的两种方法,创建箱线图要么删除我已经创建的所有子图,要么在子图网格之后绘制箱线图。但是我似乎无法在子图网格内绘制它。

import matplotlib.pyplot as plt
import pandas
from pandas import DataFrame, Series

data = {'day' : Series([1, 1, 1, 2, 2, 2, 3, 3, 3]), 
        'val' : Series([3, 4, 5, 6, 7, 8, 9, 10, 11])}
df = pandas.DataFrame(data)

我尝试的第一件事是以下内容:

plt.figure()

plt.subplot(2, 2, 1)
plt.plot([1, 2, 3])

plt.subplot(2, 2, 4)
df.boxplot('val', 'day')

但这只是在子图外创建了一个图表: 尝试A 输入图片描述 然后,我尝试手动提供轴:
plt.figure()

plt.subplot(2, 2, 1)
plt.plot([1, 2, 3])

plt.subplot(2, 2, 4)
ax = plt.gca()
df.boxplot('val', 'day', ax=ax)

但是这样做会破坏副情节网格以及最初的图像:

enter image description here

有什么办法可以让我的箱线图像出现在子图中的右下方网格中(第一组图像中为空的那个)?
1个回答

6
这似乎是pandas绘图设置中的一个错误或至少是不良行为。问题在于,如果你向boxplot提供一个by参数,pandas会发出自己的subplots调用,从而删除任何现有的子图。显然,它这样做是为了如果你想绘制多个值,它将为每个值创建子图(例如,一个按天数绘制的Y1箱形图,另一个按天数绘制的Y2箱形图等)。
然而,它应该做的事情是检查您是否只绘制一个值,如果是这种情况,则使用提供的ax对象(如果有)而不是创建自己的子图。当您只绘制一个值时,它会创建一个1x1的子图网格,这并不是很有用。它的逻辑也有点奇怪,因为它基于您要绘制的列数(第一个参数的长度)创建网格,但仅在您提供by参数时才这样做。其目的似乎是允许多个箱形图,例如df.boxplot(['col1', 'col2']),但这样做会阻止您进行合理的尝试,例如df.boxplot('col1', 'grouper1')。我建议在pandasbug tracker上提出问题。同时,一个有些hackish的解决方法是这样做:
df.pivot('val', 'day', 'val').boxplot(ax=ax)

这将重塑您的数据,使分组值(即日期)成为列。重新塑造的表格中有许多未出现在特定day值的val值的NAs,但是在绘图时会忽略这些NAs,因此您会在正确的子图位置得到正确的绘图。

错误报告已提交。与此同时,您的解决方法很有效!谢谢! - GeorgeLewis
1
经过进一步的研究,我们也可以使用内置的绘图工具来完成这个任务:from pandas.tools.plotting import boxplot_frame_groupby。 - GeorgeLewis
@GeorgeLewis,你如何使用boxplot_frame_groupby? - Amyunimus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接