Here is my problem: I want the colors of the boxplots to match the histogram colors.
In previous paired plots I iterate over datasets and when in the same loop Matplotlib
handles colors for me. ax.bxp()
(documentation) works differently than other plotting functions, taking a list of dictionaries so iterating is not necessary.
ax.bxp(list_of_dicts # from my DataFrame below
,vert=False
,showfliers=False)
When I iterate through the boxplot DataFrame rows and use ax.bxp()
the boxplots are plotted on top of one another making it useless.
What should I try next?
Sample data for creating the ax.bxp()
plot:
q1 med mean q3 whishi whislo my_data_col label
0 73.992 74.000 73.99936 74.006 73.982 74.030 obs1 obs1
1 73.995 74.001 73.99996 74.007 73.967 74.024 obs2 obs2
2 73.993 73.998 74.00100 74.009 73.986 74.021 obs3 obs3
3 73.999 74.005 74.00332 74.007 73.985 74.020 obs4 obs4
4 73.996 74.004 74.00224 74.009 73.984 74.014 obs5 obs5
You can set the colors explicitly, so you can reuse them across the histograms and boxplots.
Below is an example how you could use the batched ax.bxp()
and set colors.
If you managed to do it in a for loop but are just stuck with the boxes overlapping, then look into the positions
arg of ax.bxp()
.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
# fake data
np.random.seed(19680801)
data = np.random.lognormal(size=(37, 4), mean=1.5, sigma=1.75)
labels = list("ABCD")
# compute the boxplot stats
stats = cbook.boxplot_stats(data, labels=labels, bootstrap=10000)
for n in range(len(stats)):
stats[n]["med"] = np.median(data)
stats[n]["mean"] *= 2
# draw boxplots
fig, ax = plt.subplots()
bplots = ax.bxp(stats, patch_artist=True)
ax.set_yscale("log")
ax.set_yticklabels([])
# change colors
colors = ["blue", "red", "green", "orange"]
for patch, clr in zip(bplots["boxes"], colors):
patch.set_facecolor(clr)
plt.show()