我在子图中绘制 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')
但这只是在子图之外创建了情节:
因此,我随后尝试手动提供轴:
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)
但这只是破坏了子图网格以及初始图像:
关于如何让我的箱线图图像出现在子图中右下方的网格(第一组图像中为空的那个)的任何想法?
最佳答案
这似乎是 pandas 绘图设置中的错误,或者至少是不良行为。发生的事情是,如果您为 boxplot
提供一个 by
参数,pandas 会发出它自己的 subplots
调用,删除任何现有的子图。这样做显然是为了让如果您想绘制多个值,它将为每个值创建子图(例如,一个箱线图用于 Y1 按天,另一个箱线图用于 Y2 按天等)。
然而,它看起来应该做的,但实际上并没有,是检查你是否只绘制一个值,在这种情况下,使用提供的 ax
对象(如果有的话)而不是制作自己的子图。当您只绘制一个值时,它会创建一个 1×1 子图网格,这不是很有用。它的逻辑也有点奇怪,因为它根据您正在绘制的列的数量(第一个参数的长度)创建一个网格,但它只有在您提供 by
参数。其意图似乎是允许像 df.boxplot(['col1', 'col2'])
这样的多箱形图,但这样做会阻止您相当合理地尝试执行 df .boxplot('col1', 'grouper1')
.
我建议提出一个关于 pandas 的问题 bug tracker .
与此同时,一个有点 hackish 的解决方法是:
df.pivot('val', 'day', 'val').boxplot(ax=ax)
这会 reshape 您的数据,使分组依据值(天)成为列。 reshape 后的表有很多 val
值的 NA,这些值不会出现在特定的 day
值中,但是这些 NA 在绘图时会被忽略,因此您可以得到正确的绘图正确的子图位置。
关于python - 子图中的 Pandas 箱线图问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16500079/