here 回答了类似的问题。但是,链接的问题询问使用seaborn 而不是直接从matplotlib 生成的图。这里的解决方案是类似的,但需要一些小的调整:
import matplotlib.pyplot as plt
import numpy as np
data = np.random.normal(size=(100, 3))
fig, ax = plt.subplots(1, 1)
ax.boxplot(data)
# Loop over the 3 boxes
for i in range(3):
# Set the limits of the lower whisker to be the same as the box limits
ax.lines[i*7 + 3].set_xdata(ax.lines[i*7 + 5].get_xdata())
# Set the limits of the upper whisker to be the same as the box limits
ax.lines[i*7 + 4].set_xdata(ax.lines[i*7 + 5].get_xdata())
请注意,如果您将参数 showfliers=False 传递给对 plt.boxplot 的调用,则生成的轴将仅包含 6 行,而不是 7 行。我们的代码应变为:
for i in range(3):
ax.lines[i*6 + 3].set_xdata(ax.lines[i*6 + 5].get_xdata())
ax.lines[i*6 + 4].set_xdata(ax.lines[i*6 + 5].get_xdata())
将其他参数传递给plt.boxplot 调用可能会进一步改变我们轴的线实例的数量。当我们更改传递给plt.boxplot 的参数时必须更改我们的代码是一件痛苦的事情。
更好的解决方案是保留对plt.boxplot 的调用返回的数据并直接使用它:
fig, ax = plt.subplots(1, 1)
# Keep hold of the returned
box = ax.boxplot(data)
# Loop over the 3 boxes
for i in range(3):
# Adjust the lower cap
box['caps'][2*i].set_xdata(box['boxes'][i].get_xdata()[:2])
# Adjust the upper cap
box['caps'][2*i + 1].set_xdata(box['boxes'][i].get_xdata()[:2])
这更好,尽管我们仍在对 3 个箱线图 (range(3)) 进行硬编码。我们可以摆脱它:
fig, ax = plt.subplots(1, 1)
# Keep hold of the returned
box = ax.boxplot(data)
# Loop over the n boxes
for i, box_lines in enumerate(box['boxes']):
# Adjust the lower cap
box['caps'][2*i].set_xdata(box_lines.get_xdata()[:2])
# Adjust the upper cap
box['caps'][2*i + 1].set_xdata(box_lines.get_xdata()[:2])
此外,如果我们改为更改 ydata,水平箱线图也可以获得相同的结果:
fig, ax = plt.subplots(1, 1)
box = ax.boxplot(data, vert=False)
# Loop over the n boxes
for i, box_lines in enumerate(box['boxes']):
# Adjust the lower cap
box['caps'][2*i].set_ydata(box_lines.get_ydata()[:2])
# Adjust the upper cap
box['caps'][2*i + 1].set_ydata(box_lines.get_ydata()[:2])