8

I have three algorithms, A, B, and C. I've run them on different datasets and would like to graph their runtimes on each as a grouped boxplot in Python.

As a visual example of what I want, I made a terrible drawing, but hopefully it gets the point across.

boxplot graph drawing

If my data in python looks like this:

import numpy as np import random data = {} data['dataset1'] = {} data['dataset2'] = {} data['dataset3'] = {} n = 5 for k,v in data.iteritems(): upper = random.randint(0, 1000) v['A'] = np.random.uniform(0, upper, size=n) v['B'] = np.random.uniform(0, upper, size=n) v['C'] = np.random.uniform(0, upper, size=n) 

How can I make my plot look like the picture I drew?

2

1 Answer 1

18

It's easiest to do this with independent subplots:

import matplotlib.pyplot as plt import numpy as np import random data = {} data['dataset1'] = {} data['dataset2'] = {} data['dataset3'] = {} n = 500 for k,v in data.iteritems(): upper = random.randint(0, 1000) v['A'] = np.random.uniform(0, upper, size=n) v['B'] = np.random.uniform(0, upper, size=n) v['C'] = np.random.uniform(0, upper, size=n) fig, axes = plt.subplots(ncols=3, sharey=True) fig.subplots_adjust(wspace=0) for ax, name in zip(axes, ['dataset1', 'dataset2', 'dataset3']): ax.boxplot([data[name][item] for item in ['A', 'B', 'C']]) ax.set(xticklabels=['A', 'B', 'C'], xlabel=name) ax.margins(0.05) # Optional plt.show() 

enter image description here

Sign up to request clarification or add additional context in comments.

5 Comments

perfectly what I wanted! thanks. always amazed how versatile matplotlib in python is.
@lollercoaster - Happy to help! Your sketch and example data made your question very clear and easy to answer, for whatever it's worth. Excellent question!
@JoeKington How did you get rid of the yticklabels on plots 2 and 3? They appear on all three plots for me, and if I remove them from one they disappear from all three because the yaxis is shared.
@Deditos - Using subplots with sharey=True should automatically hide them, but if it's not for some reason, use plt.setp(ax2.get_yticklabels(), visible=False) (and repeat for ax3). What you're running into is a bit of a classic gotcha with shared axes. The plt.setp(..., visible=False) is a workaround so that they're still shown on the first axes, but not on the other shared ones.
@JoeKington: It's probably because I'm using an old matplotlib version, but that manual setp command does the trick, thanks!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.