|
1 | 1 | """ |
2 | | -======================= |
3 | | -Boxplot drawer function |
4 | | -======================= |
5 | | -
|
6 | | -This example demonstrates how to pass pre-computed box plot |
7 | | -statistics to the box plot drawer. The first figure demonstrates |
8 | | -how to remove and add individual components (note that the |
9 | | -mean is the only value not shown by default). The second |
10 | | -figure demonstrates how the styles of the artists can |
11 | | -be customized. |
12 | | -
|
13 | | -A good general reference on boxplots and their history can be found |
14 | | -here: http://vita.had.co.nz/papers/boxplots.pdf |
15 | | -""" |
16 | | - |
17 | | -import matplotlib.pyplot as plt |
18 | | -import numpy as np |
19 | | - |
20 | | -import matplotlib.cbook as cbook |
| 2 | +============================================= |
| 3 | +Separate calculation and plotting of boxplots |
| 4 | +============================================= |
21 | 5 |
|
22 | | -# fake data |
23 | | -np.random.seed(19680801) |
24 | | -data = np.random.lognormal(size=(37, 4), mean=1.5, sigma=1.75) |
25 | | -labels = list('ABCD') |
26 | | - |
27 | | -# compute the boxplot stats |
28 | | -stats = cbook.boxplot_stats(data, labels=labels, bootstrap=10000) |
| 6 | +Drawing a `~.axes.Axes.boxplot` for a given data set, consists of two main operations, |
| 7 | +that can also be used separately: |
29 | 8 |
|
30 | | -# %% |
31 | | -# After we've computed the stats, we can go through and change anything. |
32 | | -# Just to prove it, I'll set the median of each set to the median of all |
33 | | -# the data, and double the means |
| 9 | +1. Calculating the boxplot statistics: `matplotlib.cbook.boxplot_stats` |
| 10 | +2. Drawing the boxplot: `matplotlib.axes.Axes.bxp` |
34 | 11 |
|
35 | | -for n in range(len(stats)): |
36 | | - stats[n]['med'] = np.median(data) |
37 | | - stats[n]['mean'] *= 2 |
| 12 | +Thus, ``ax.boxplot(data)`` is equivalent to :: |
38 | 13 |
|
39 | | -print(list(stats[0])) |
| 14 | + stats = cbook.boxplot_stats(data) |
| 15 | + ax.bxp(stats) |
40 | 16 |
|
41 | | -fs = 10 # fontsize |
42 | | - |
43 | | -# %% |
44 | | -# Demonstrate how to toggle the display of different elements: |
| 17 | +All styling keyword arguments are identical between `~.axes.Axes.boxplot` and |
| 18 | +`~.axes.Axes.bxp`, and they are passed through from `~.axes.Axes.boxplot` to |
| 19 | +`~.axes.Axes.bxp`. However, the *tick_labels* parameter of `~.axes.Axes.boxplot` |
| 20 | +translates to a generic *labels* parameter in `.boxplot_stats`, because the labels are |
| 21 | +data-related and attached to the returned per-dataset dictionaries. |
45 | 22 |
|
46 | | -fig, axs = plt.subplots(nrows=2, ncols=3, figsize=(6, 6), sharey=True) |
47 | | -axs[0, 0].bxp(stats) |
48 | | -axs[0, 0].set_title('Default', fontsize=fs) |
| 23 | +The following code demonstrates the equivalence between the two methods. |
49 | 24 |
|
50 | | -axs[0, 1].bxp(stats, showmeans=True) |
51 | | -axs[0, 1].set_title('showmeans=True', fontsize=fs) |
| 25 | +""" |
| 26 | +# sphinx_gallery_thumbnail_number = 2 |
52 | 27 |
|
53 | | -axs[0, 2].bxp(stats, showmeans=True, meanline=True) |
54 | | -axs[0, 2].set_title('showmeans=True,\nmeanline=True', fontsize=fs) |
| 28 | +import matplotlib.pyplot as plt |
| 29 | +import numpy as np |
55 | 30 |
|
56 | | -axs[1, 0].bxp(stats, showbox=False, showcaps=False) |
57 | | -tufte_title = 'Tufte Style\n(showbox=False,\nshowcaps=False)' |
58 | | -axs[1, 0].set_title(tufte_title, fontsize=fs) |
| 31 | +from matplotlib import cbook |
59 | 32 |
|
60 | | -axs[1, 1].bxp(stats, shownotches=True) |
61 | | -axs[1, 1].set_title('notch=True', fontsize=fs) |
| 33 | +np.random.seed(19680801) |
| 34 | +data = np.random.randn(20, 3) |
62 | 35 |
|
63 | | -axs[1, 2].bxp(stats, showfliers=False) |
64 | | -axs[1, 2].set_title('showfliers=False', fontsize=fs) |
| 36 | +fig, (ax1, ax2) = plt.subplots(1, 2) |
65 | 37 |
|
66 | | -for ax in axs.flat: |
67 | | - ax.set_yscale('log') |
68 | | - ax.set_yticklabels([]) |
| 38 | +# single boxplot call |
| 39 | +ax1.boxplot(data, tick_labels=['A', 'B', 'C'], |
| 40 | + patch_artist=True, boxprops={'facecolor': 'bisque'}) |
69 | 41 |
|
70 | | -fig.subplots_adjust(hspace=0.4) |
71 | | -plt.show() |
| 42 | +# separate calculation of statistics and plotting |
| 43 | +stats = cbook.boxplot_stats(data, labels=['A', 'B', 'C']) |
| 44 | +ax2.bxp(stats, patch_artist=True, boxprops={'facecolor': 'bisque'}) |
72 | 45 |
|
73 | 46 | # %% |
74 | | -# Demonstrate how to customize the display different elements: |
75 | | - |
76 | | -boxprops = dict(linestyle='--', linewidth=3, color='darkgoldenrod') |
77 | | -flierprops = dict(marker='o', markerfacecolor='green', markersize=12, |
78 | | - linestyle='none') |
79 | | -medianprops = dict(linestyle='-.', linewidth=2.5, color='firebrick') |
80 | | -meanpointprops = dict(marker='D', markeredgecolor='black', |
81 | | - markerfacecolor='firebrick') |
82 | | -meanlineprops = dict(linestyle='--', linewidth=2.5, color='purple') |
83 | | - |
84 | | -fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(6, 6), sharey=True) |
85 | | -axs[0, 0].bxp(stats, boxprops=boxprops) |
86 | | -axs[0, 0].set_title('Custom boxprops', fontsize=fs) |
87 | | - |
88 | | -axs[0, 1].bxp(stats, flierprops=flierprops, medianprops=medianprops) |
89 | | -axs[0, 1].set_title('Custom medianprops\nand flierprops', fontsize=fs) |
| 47 | +# Using the separate functions allows to pre-calculate statistics, in case you need |
| 48 | +# them explicitly for other purposes, or to reuse the statistics for multiple plots. |
| 49 | +# |
| 50 | +# Conversely, you can also use the `~.axes.Axes.bxp` function directly, if you already |
| 51 | +# have the statistical parameters: |
90 | 52 |
|
91 | | -axs[1, 0].bxp(stats, meanprops=meanpointprops, meanline=False, |
92 | | - showmeans=True) |
93 | | -axs[1, 0].set_title('Custom mean\nas point', fontsize=fs) |
| 53 | +fig, ax = plt.subplots() |
94 | 54 |
|
95 | | -axs[1, 1].bxp(stats, meanprops=meanlineprops, meanline=True, |
96 | | - showmeans=True) |
97 | | -axs[1, 1].set_title('Custom mean\nas line', fontsize=fs) |
| 55 | +stats = [ |
| 56 | + dict(med=0, q1=-1, q3=1, whislo=-2, whishi=2, fliers=[-4, -3, 3, 4], label='A'), |
| 57 | + dict(med=0, q1=-2, q3=2, whislo=-3, whishi=3, fliers=[], label='B'), |
| 58 | + dict(med=0, q1=-3, q3=3, whislo=-4, whishi=4, fliers=[], label='C'), |
| 59 | +] |
98 | 60 |
|
99 | | -for ax in axs.flat: |
100 | | - ax.set_yscale('log') |
101 | | - ax.set_yticklabels([]) |
| 61 | +ax.bxp(stats, patch_artist=True, boxprops={'facecolor': 'bisque'}) |
102 | 62 |
|
103 | | -fig.suptitle("I never said they'd be pretty") |
104 | | -fig.subplots_adjust(hspace=0.4) |
105 | 63 | plt.show() |
106 | 64 |
|
107 | 65 | # %% |
|
112 | 70 | # in this example: |
113 | 71 | # |
114 | 72 | # - `matplotlib.axes.Axes.bxp` |
| 73 | +# - `matplotlib.axes.Axes.boxplot` |
115 | 74 | # - `matplotlib.cbook.boxplot_stats` |
0 commit comments