I have a series of box plots I am trying to make, each of which has a different range. I tried setting ylim by determining the max and min of each separate series. Howe
You could set showfliers=False
in the boxplot, so the outliers don't get plotted.
Since you ask specifically about the whiskers, this is how they are calculated, with a default of 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’.
You could do the same calculation and set your ylim
to that.
You could inspect the whiskers (maplotlib.lines.Line2D
objects) returned by df.boxplot()
. For example, if you call
bp = df.boxplot(ax=ax)
then bp['whiskers']
will be a list of Line2D
objects. You can find the y-values
for each line using
yval = np.concatenate([line.get_ydata() for line in bp['whiskers']])
and then use yval.min()
and yval.max()
to determine the desired y-limits
.
For example,
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()
yields
As an alternative to what @unutbu suggested, you could avoid plotting the outliers and then use ax.margins(y=0)
(or some small eps
) to scale the limits to the range of the whiskers.
For example:
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()
And if you'd like a bit of room around the largest "whiskers", use ax.margins(0.05)
to add 5% of the range instead of 0% of the range:
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()