以 xticks 为中心的 Pyplot 箱线图
Pyplot boxplots centered around xticks
我有一系列箱线图,我想以 xticks 为中心(特别是每个 xtick 2 个)。考虑以下因素:
# fake up some more data
spread= rand(50) * 100
center = ones(25) * 40
flier_high = rand(10) * 100 + 100
flier_low = rand(10) * -100
d2 = concatenate( (spread, center, flier_high, flier_low), 0 )
data.shape = (-1, 1)
d2.shape = (-1, 1)
#data = concatenate( (data, d2), 1 )
# Making a 2-D array only works if all the columns are the
# same length. If they are not, then use a list instead.
# This is actually more efficient because boxplot converts
# a 2-D array into a list of vectors internally anyway.
data = [data, d2, d2[::2,0]]
# multiple box plots on one figure
figure()
boxplot(data)
产生
但是我想要 6 个箱形图,其中 2 个以 1 为中心,2 个以 2 为中心,依此类推...如果我再添加三个,它只会将它们添加到 4,5,6...任何帮助都会受到赞赏
编辑 清楚我所说的 "centered" 的意思。我想要一个箱线图就在标记为“1”的 xtick 左侧,另一个箱线图就在右侧。它们可能会在 y 范围内重叠,所以我不希望它们被绘制在彼此之上。
要控制箱线图的 x-position,请使用 positions
kwarg。
例如:
import numpy as np
import matplotlib.pyplot as plt
dists = [np.random.normal(i, 1, 100) for i in range(0, 10, 2)]
fig, ax = plt.subplots()
ax.boxplot(dists, positions=[0, 1, 2, 0, 1])
plt.show()
如果您希望分组 side-by-side,您需要自己计算位置。一种方法可能是这样的:
def grouped_boxplots(data_groups, ax=None, max_width=0.8, pad=0.05, **kwargs):
if ax is None:
ax = plt.gca()
max_group_size = max(len(item) for item in data_groups)
total_padding = pad * (max_group_size - 1)
width = (max_width - total_padding) / max_group_size
kwargs['widths'] = width
def positions(group, i):
span = width * len(group) + pad * (len(group) - 1)
ends = (span - width) / 2
x = np.linspace(-ends, ends, len(group))
return x + i
artists = []
for i, group in enumerate(data_groups, start=1):
artist = ax.boxplot(group, positions=positions(group, i), **kwargs)
artists.append(artist)
ax.margins(0.05)
ax.set(xticks=np.arange(len(data_groups)) + 1)
ax.autoscale()
return artists
作为使用它的快速示例:
data = [[np.random.normal(i, 1, 30) for i in range(2)],
[np.random.normal(i, 1.5, 30) for i in range(3)],
[np.random.normal(i, 2, 30) for i in range(4)]]
grouped_boxplots(data)
plt.show()
...为了展示一个过于花哨的例子:
import numpy as np
import matplotlib.pyplot as plt
def main():
data = [[np.random.normal(i, 1, 30) for i in range(2)],
[np.random.normal(i, 1.5, 30) for i in range(3)],
[np.random.normal(i, 2, 30) for i in range(4)]]
fig, ax = plt.subplots()
groups = grouped_boxplots(data, ax, max_width=0.9,
patch_artist=True, notch=True)
colors = ['lavender', 'lightblue', 'bisque', 'lightgreen']
for item in groups:
for color, patch in zip(colors, item['boxes']):
patch.set(facecolor=color)
proxy_artists = groups[-1]['boxes']
ax.legend(proxy_artists, ['Group A', 'Group B', 'Group C', 'Group D'],
loc='best')
ax.set(xlabel='Year', ylabel='Performance', axisbelow=True,
xticklabels=['2012', '2013', '2014'])
ax.grid(axis='y', ls='-', color='white', lw=2)
ax.patch.set(facecolor='0.95')
plt.show()
def grouped_boxplots(data_groups, ax=None, max_width=0.8, pad=0.05, **kwargs):
if ax is None:
ax = plt.gca()
max_group_size = max(len(item) for item in data_groups)
total_padding = pad * (max_group_size - 1)
width = (max_width - total_padding) / max_group_size
kwargs['widths'] = width
def positions(group, i):
span = width * len(group) + pad * (len(group) - 1)
ends = (span - width) / 2
x = np.linspace(-ends, ends, len(group))
return x + i
artists = []
for i, group in enumerate(data_groups, start=1):
artist = ax.boxplot(group, positions=positions(group, i), **kwargs)
artists.append(artist)
ax.margins(0.05)
ax.set(xticks=np.arange(len(data_groups)) + 1)
ax.autoscale()
return artists
main()
我有一系列箱线图,我想以 xticks 为中心(特别是每个 xtick 2 个)。考虑以下因素:
# fake up some more data
spread= rand(50) * 100
center = ones(25) * 40
flier_high = rand(10) * 100 + 100
flier_low = rand(10) * -100
d2 = concatenate( (spread, center, flier_high, flier_low), 0 )
data.shape = (-1, 1)
d2.shape = (-1, 1)
#data = concatenate( (data, d2), 1 )
# Making a 2-D array only works if all the columns are the
# same length. If they are not, then use a list instead.
# This is actually more efficient because boxplot converts
# a 2-D array into a list of vectors internally anyway.
data = [data, d2, d2[::2,0]]
# multiple box plots on one figure
figure()
boxplot(data)
产生
但是我想要 6 个箱形图,其中 2 个以 1 为中心,2 个以 2 为中心,依此类推...如果我再添加三个,它只会将它们添加到 4,5,6...任何帮助都会受到赞赏
编辑 清楚我所说的 "centered" 的意思。我想要一个箱线图就在标记为“1”的 xtick 左侧,另一个箱线图就在右侧。它们可能会在 y 范围内重叠,所以我不希望它们被绘制在彼此之上。
要控制箱线图的 x-position,请使用 positions
kwarg。
例如:
import numpy as np
import matplotlib.pyplot as plt
dists = [np.random.normal(i, 1, 100) for i in range(0, 10, 2)]
fig, ax = plt.subplots()
ax.boxplot(dists, positions=[0, 1, 2, 0, 1])
plt.show()
如果您希望分组 side-by-side,您需要自己计算位置。一种方法可能是这样的:
def grouped_boxplots(data_groups, ax=None, max_width=0.8, pad=0.05, **kwargs):
if ax is None:
ax = plt.gca()
max_group_size = max(len(item) for item in data_groups)
total_padding = pad * (max_group_size - 1)
width = (max_width - total_padding) / max_group_size
kwargs['widths'] = width
def positions(group, i):
span = width * len(group) + pad * (len(group) - 1)
ends = (span - width) / 2
x = np.linspace(-ends, ends, len(group))
return x + i
artists = []
for i, group in enumerate(data_groups, start=1):
artist = ax.boxplot(group, positions=positions(group, i), **kwargs)
artists.append(artist)
ax.margins(0.05)
ax.set(xticks=np.arange(len(data_groups)) + 1)
ax.autoscale()
return artists
作为使用它的快速示例:
data = [[np.random.normal(i, 1, 30) for i in range(2)],
[np.random.normal(i, 1.5, 30) for i in range(3)],
[np.random.normal(i, 2, 30) for i in range(4)]]
grouped_boxplots(data)
plt.show()
...为了展示一个过于花哨的例子:
import numpy as np
import matplotlib.pyplot as plt
def main():
data = [[np.random.normal(i, 1, 30) for i in range(2)],
[np.random.normal(i, 1.5, 30) for i in range(3)],
[np.random.normal(i, 2, 30) for i in range(4)]]
fig, ax = plt.subplots()
groups = grouped_boxplots(data, ax, max_width=0.9,
patch_artist=True, notch=True)
colors = ['lavender', 'lightblue', 'bisque', 'lightgreen']
for item in groups:
for color, patch in zip(colors, item['boxes']):
patch.set(facecolor=color)
proxy_artists = groups[-1]['boxes']
ax.legend(proxy_artists, ['Group A', 'Group B', 'Group C', 'Group D'],
loc='best')
ax.set(xlabel='Year', ylabel='Performance', axisbelow=True,
xticklabels=['2012', '2013', '2014'])
ax.grid(axis='y', ls='-', color='white', lw=2)
ax.patch.set(facecolor='0.95')
plt.show()
def grouped_boxplots(data_groups, ax=None, max_width=0.8, pad=0.05, **kwargs):
if ax is None:
ax = plt.gca()
max_group_size = max(len(item) for item in data_groups)
total_padding = pad * (max_group_size - 1)
width = (max_width - total_padding) / max_group_size
kwargs['widths'] = width
def positions(group, i):
span = width * len(group) + pad * (len(group) - 1)
ends = (span - width) / 2
x = np.linspace(-ends, ends, len(group))
return x + i
artists = []
for i, group in enumerate(data_groups, start=1):
artist = ax.boxplot(group, positions=positions(group, i), **kwargs)
artists.append(artist)
ax.margins(0.05)
ax.set(xticks=np.arange(len(data_groups)) + 1)
ax.autoscale()
return artists
main()