Matplotlib - 如何为一系列绘图设置 ylim()?

Matplotlib - How do I set ylim() for a series of plots?

我正在尝试绘制一系列箱线图,每个箱线图都有不同的范围。我尝试通过确定每个单独系列的最大值和最小值来设置 ylim。然而,在许多情况下,最小值是异常值,因此图被压缩了。我怎样才能 select 与情节的 'whiskers' 使用的相同限制(加上一个小的边距)?

例如,现在我正在这样做:

[In]
ax = df['feature'].boxplot()
ymax = max(df['feature']
ymin = min(df['feature']
ax.set_ylim([ymax,ymin])

我想将 ymax、ymin 设置为箱线图的须线。

您可以检查 df.boxplot() 返回的胡须(maplotlib.lines.Line2D 个对象)。例如,如果您调用

bp = df.boxplot(ax=ax)

然后 bp['whiskers'] 将是 Line2D 个对象的列表。您可以使用

找到每一行的 y-values
yval = np.concatenate([line.get_ydata() for line in bp['whiskers']])

然后使用yval.min()yval.max()确定所需的y-limits


例如,

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
df = pd.DataFrame(np.random.poisson(5, size=(100, 5)))
bp = df.boxplot(ax=ax)
yval = np.concatenate([line.get_ydata() for line in bp['whiskers']])
eps = 1.0
ymin, ymax = yval.min()-eps, yval.max()+eps
ax.set_ylim([ymin,ymax])
plt.show()

产量

您可以在箱线图中设置 showfliers=False,这样异常值就不会被绘制出来。

由于您专门询问了胡须,this is how they are calculated,默认值为 1.5:

whis : float, sequence (default = 1.5) or string

As a float, determines the reach of the whiskers past the first and third quartiles (e.g., Q3 + whis*IQR, IQR = interquartile range, Q3-Q1). Beyond the whiskers, data are considered outliers and are plotted as individual points. Set this to an unreasonably high value to force the whiskers to show the min and max values. Alternatively, set this to an ascending sequence of percentile (e.g., [5, 95]) to set the whiskers at specific percentiles of the data. Finally, whis can be the string ‘range’ to force the whiskers to the min and max of the data. In the edge case that the 25th and 75th percentiles are equivalent, whis will be automatically set to ‘range’.

您可以进行相同的计算并将 ylim 设置为该值。

作为@unutbu 建议的替代方案,您可以避免绘制异常值,然后使用 ax.margins(y=0)(或一些小的 eps)将限制缩放到晶须范围。

例如:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(np.random.poisson(5, size=(100, 5)))

fig, ax = plt.subplots()
#Note showfliers=False is more readable, but requires a recent version iirc
box = df.boxplot(ax=ax, sym='') 
ax.margins(y=0)
plt.show()

如果您想在最大 "whiskers" 周围留出一些空间,请使用 ax.margins(0.05) 添加范围的 5% 而不是范围的 0%:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(np.random.poisson(5, size=(100, 5)))

fig, ax = plt.subplots()
box = df.boxplot(ax=ax, sym='')
ax.margins(y=0.05)
plt.show()