Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print the box, whiskers and outlier values in box and whisker plots

I have plotted a box and whiskers plot for my data

My Code:

red_diamond = dict(markerfacecolor='r', marker='D')
fig3, ax3 = plt.subplots()
ax3.set_title('Changed Outlier Symbols')
ax3.boxplot(maximum.values[:,1], flierprops=red_diamond)

and I obtained a plot as follows: enter image description here

What I want to do: Print the values of the whiskers, the outliers (red diamonds), the quartiles and the median on the plot itself.

like image 998
Junkrat Avatar asked Oct 16 '25 16:10

Junkrat


1 Answers

ax.boxplot returns a dictionary with all the lines that are plotted in the making of the box and whisker plot. One option would be to interrogate this dictionary, and create labels from the information it contains. The relevant keys are:

  • boxes for the IQR
  • medians for the median
  • caps for the whiskers
  • fliers for the outliers

Note, the function below only really works for a single boxplot (if you create multiple boxes in one go, you will need to be more careful how you grab the information from the dictionary).

An alternative would be to find the information from the data array itself (finding the median and IQR is easy). I'm not sure exactly how matplotlib determines what a flier is and where the caps should go. If you want do that, it should be easy enough to modify the function below.

import matplotlib.pyplot as plt
import numpy as np

# Make some dummy data
np.random.seed(1)
dummy_data = np.random.lognormal(size=40)

def make_labels(ax, boxplot):

    # Grab the relevant Line2D instances from the boxplot dictionary
    iqr = boxplot['boxes'][0]
    caps = boxplot['caps']
    med = boxplot['medians'][0]
    fly = boxplot['fliers'][0]

    # The x position of the median line
    xpos = med.get_xdata()

    # Lets make the text have a horizontal offset which is some 
    # fraction of the width of the box
    xoff = 0.10 * (xpos[1] - xpos[0])

    # The x position of the labels
    xlabel = xpos[1] + xoff

    # The median is the y-position of the median line
    median = med.get_ydata()[1]

    # The 25th and 75th percentiles are found from the
    # top and bottom (max and min) of the box
    pc25 = iqr.get_ydata().min()
    pc75 = iqr.get_ydata().max()

    # The caps give the vertical position of the ends of the whiskers
    capbottom = caps[0].get_ydata()[0]
    captop = caps[1].get_ydata()[0]

    # Make some labels on the figure using the values derived above
    ax.text(xlabel, median,
            'Median = {:6.3g}'.format(median), va='center')
    ax.text(xlabel, pc25,
            '25th percentile = {:6.3g}'.format(pc25), va='center')
    ax.text(xlabel, pc75,
            '75th percentile = {:6.3g}'.format(pc75), va='center')
    ax.text(xlabel, capbottom,
            'Bottom cap = {:6.3g}'.format(capbottom), va='center')
    ax.text(xlabel, captop,
            'Top cap = {:6.3g}'.format(captop), va='center')

    # Many fliers, so we loop over them and create a label for each one
    for flier in fly.get_ydata():
        ax.text(1 + xoff, flier,
                'Flier = {:6.3g}'.format(flier), va='center')

# Make the figure
red_diamond = dict(markerfacecolor='r', marker='D')
fig3, ax3 = plt.subplots()
ax3.set_title('Changed Outlier Symbols')

# Create the boxplot and store the resulting python dictionary
my_boxes = ax3.boxplot(dummy_data, flierprops=red_diamond)

# Call the function to make labels
make_labels(ax3, my_boxes)

plt.show()

enter image description here

like image 64
tmdavison Avatar answered Oct 19 '25 06:10

tmdavison