.. note:: :class: sphx-glr-download-link-note Click :ref:`here ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_gallery_statistics_boxplot_demo.py: ======== Boxplots ======== Visualizing boxplots with matplotlib. The following examples show off how to visualize boxplots with Matplotlib. There are many options to control their appearance and the statistics that they use to summarize the data. .. code-block:: default import matplotlib.pyplot as plt import numpy as np from matplotlib.patches import Polygon # Fixing random state for reproducibility np.random.seed(19680801) # fake up some data spread = np.random.rand(50) * 100 center = np.ones(25) * 50 flier_high = np.random.rand(10) * 100 + 100 flier_low = np.random.rand(10) * -100 data = np.concatenate((spread, center, flier_high, flier_low), 0) fig, axs = plt.subplots(2, 3) # basic plot axs[0, 0].boxplot(data) axs[0, 0].set_title('basic plot') # notched plot axs[0, 1].boxplot(data, 1) axs[0, 1].set_title('notched plot') # change outlier point symbols axs[0, 2].boxplot(data, 0, 'gD') axs[0, 2].set_title('change outlier\npoint symbols') # don't show outlier points axs[1, 0].boxplot(data, 0, '') axs[1, 0].set_title("don't show\noutlier points") # horizontal boxes axs[1, 1].boxplot(data, 0, 'rs', 0) axs[1, 1].set_title('horizontal boxes') # change whisker length axs[1, 2].boxplot(data, 0, 'rs', 0, 0.75) axs[1, 2].set_title('change whisker length') fig.subplots_adjust(left=0.08, right=0.98, bottom=0.05, top=0.9, hspace=0.4, wspace=0.3) # fake up some more data spread = np.random.rand(50) * 100 center = np.ones(25) * 40 flier_high = np.random.rand(10) * 100 + 100 flier_low = np.random.rand(10) * -100 d2 = np.concatenate((spread, center, flier_high, flier_low), 0) data.shape = (-1, 1) d2.shape = (-1, 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 Axes fig, ax = plt.subplots() ax.boxplot(data) plt.show() .. rst-class:: sphx-glr-horizontal * .. image:: /gallery/statistics/images/sphx_glr_boxplot_demo_001.png :class: sphx-glr-multi-img * .. image:: /gallery/statistics/images/sphx_glr_boxplot_demo_002.png :class: sphx-glr-multi-img Below we'll generate data from five different probability distributions, each with different characteristics. We want to play with how an IID bootstrap resample of the data preserves the distributional properties of the original sample, and a boxplot is one visual tool to make this assessment .. code-block:: default numDists = 5 randomDists = ['Normal(1,1)', ' Lognormal(1,1)', 'Exp(1)', 'Gumbel(6,4)', 'Triangular(2,9,11)'] N = 500 norm = np.random.normal(1, 1, N) logn = np.random.lognormal(1, 1, N) expo = np.random.exponential(1, N) gumb = np.random.gumbel(6, 4, N) tria = np.random.triangular(2, 9, 11, N) # Generate some random indices that we'll use to resample the original data # arrays. For code brevity, just use the same random indices for each array bootstrapIndices = np.random.random_integers(0, N - 1, N) normBoot = norm[bootstrapIndices] expoBoot = expo[bootstrapIndices] gumbBoot = gumb[bootstrapIndices] lognBoot = logn[bootstrapIndices] triaBoot = tria[bootstrapIndices] data = [norm, normBoot, logn, lognBoot, expo, expoBoot, gumb, gumbBoot, tria, triaBoot] fig, ax1 = plt.subplots(figsize=(10, 6)) fig.canvas.set_window_title('A Boxplot Example') fig.subplots_adjust(left=0.075, right=0.95, top=0.9, bottom=0.25) bp = ax1.boxplot(data, notch=0, sym='+', vert=1, whis=1.5) plt.setp(bp['boxes'], color='black') plt.setp(bp['whiskers'], color='black') plt.setp(bp['fliers'], color='red', marker='+') # Add a horizontal grid to the plot, but make it very light in color # so we can use it for reading data values but not be distracting ax1.yaxis.grid(True, linestyle='-', which='major', color='lightgrey', alpha=0.5) # Hide these grid behind plot objects ax1.set_axisbelow(True) ax1.set_title('Comparison of IID Bootstrap Resampling Across Five Distributions') ax1.set_xlabel('Distribution') ax1.set_ylabel('Value') # Now fill the boxes with desired colors boxColors = ['darkkhaki', 'royalblue'] numBoxes = numDists*2 medians = list(range(numBoxes)) for i in range(numBoxes): box = bp['boxes'][i] boxX = [] boxY = [] for j in range(5): boxX.append(box.get_xdata()[j]) boxY.append(box.get_ydata()[j]) boxCoords = np.column_stack([boxX, boxY]) # Alternate between Dark Khaki and Royal Blue k = i % 2 boxPolygon = Polygon(boxCoords, facecolor=boxColors[k]) ax1.add_patch(boxPolygon) # Now draw the median lines back over what we just filled in med = bp['medians'][i] medianX = [] medianY = [] for j in range(2): medianX.append(med.get_xdata()[j]) medianY.append(med.get_ydata()[j]) ax1.plot(medianX, medianY, 'k') medians[i] = medianY[0] # Finally, overplot the sample averages, with horizontal alignment # in the center of each box ax1.plot([np.average(med.get_xdata())], [np.average(data[i])], color='w', marker='*', markeredgecolor='k') # Set the axes ranges and axes labels ax1.set_xlim(0.5, numBoxes + 0.5) top = 40 bottom = -5 ax1.set_ylim(bottom, top) ax1.set_xticklabels(np.repeat(randomDists, 2), rotation=45, fontsize=8) # Due to the Y-axis scale being different across samples, it can be # hard to compare differences in medians across the samples. Add upper # X-axis tick labels with the sample medians to aid in comparison # (just use two decimal places of precision) pos = np.arange(numBoxes) + 1 upperLabels = [str(np.round(s, 2)) for s in medians] weights = ['bold', 'semibold'] for tick, label in zip(range(numBoxes), ax1.get_xticklabels()): k = tick % 2 ax1.text(pos[tick], top - (top*0.05), upperLabels[tick], horizontalalignment='center', size='x-small', weight=weights[k], color=boxColors[k]) # Finally, add a basic legend fig.text(0.80, 0.08, str(N) + ' Random Numbers', backgroundcolor=boxColors[0], color='black', weight='roman', size='x-small') fig.text(0.80, 0.045, 'IID Bootstrap Resample', backgroundcolor=boxColors[1], color='white', weight='roman', size='x-small') fig.text(0.80, 0.015, '*', color='white', backgroundcolor='silver', weight='roman', size='medium') fig.text(0.815, 0.013, ' Average Value', color='black', weight='roman', size='x-small') plt.show() .. image:: /gallery/statistics/images/sphx_glr_boxplot_demo_003.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out Out: .. code-block:: none /home/tcaswell/source/p/mlp22x/examples/statistics/boxplot_demo.py:98: DeprecationWarning: This function is deprecated. Please call randint(0, 499 + 1) instead bootstrapIndices = np.random.random_integers(0, N - 1, N) Here we write a custom function to bootstrap confidence intervals. We can then use the boxplot along with this function to show these intervals. .. code-block:: default def fakeBootStrapper(n): ''' This is just a placeholder for the user's method of bootstrapping the median and its confidence intervals. Returns an arbitrary median and confidence intervals packed into a tuple ''' if n == 1: med = 0.1 CI = (-0.25, 0.25) else: med = 0.2 CI = (-0.35, 0.50) return med, CI inc = 0.1 e1 = np.random.normal(0, 1, size=(500,)) e2 = np.random.normal(0, 1, size=(500,)) e3 = np.random.normal(0, 1 + inc, size=(500,)) e4 = np.random.normal(0, 1 + 2*inc, size=(500,)) treatments = [e1, e2, e3, e4] med1, CI1 = fakeBootStrapper(1) med2, CI2 = fakeBootStrapper(2) medians = [None, None, med1, med2] conf_intervals = [None, None, CI1, CI2] fig, ax = plt.subplots() pos = np.array(range(len(treatments))) + 1 bp = ax.boxplot(treatments, sym='k+', positions=pos, notch=1, bootstrap=5000, usermedians=medians, conf_intervals=conf_intervals) ax.set_xlabel('treatment') ax.set_ylabel('response') plt.setp(bp['whiskers'], color='k', linestyle='-') plt.setp(bp['fliers'], markersize=3.0) plt.show() .. image:: /gallery/statistics/images/sphx_glr_boxplot_demo_004.png :class: sphx-glr-single-img .. _sphx_glr_download_gallery_statistics_boxplot_demo.py: .. only :: html .. container:: sphx-glr-footer :class: sphx-glr-footer-example .. container:: sphx-glr-download :download:`Download Python source code: boxplot_demo.py ` .. container:: sphx-glr-download :download:`Download Jupyter notebook: boxplot_demo.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature Keywords: matplotlib code example, codex, python plot, pyplot `Gallery generated by Sphinx-Gallery `_