|
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