I am trying to plot swarm plots and box plots together using matplotlib and Seaborn. I found how to plot them together but the box plot appears underneath the swarm plot. The problem with this is that the swarm plot points drown out the box plot and the box plot is lost. I thought that by switching the order of the functions called, to have the box plot called first rather than second as in the link below, would overlay the box plot on top but it does not.
Is it possible to overlay the box plot on top of the swarm plot points? If not, is it possible to create lines indicating where the quartiles are?
Code:
swarm_name = "Swarm_Plot_01"
#
sns.set_style("whitegrid")
ax = sns.boxplot( data = [df.Rate_VL1R, df.Rate_V12R, df.Rate_V23R, df.Rate_VM3R ],
showcaps=False,boxprops={'facecolor':'None'},
showfliers=False,whiskerprops={'linewidth':0})
ax = sns.swarmplot( data = [df.Rate_VL1R, df.Rate_V12R, df.Rate_V23R, df.Rate_VM3R ] )
plt.show()
fig = ax.get_figure()
fig.savefig(swarm_name)
plt.figure()
This question is related to, but not exactly the same, as How to create a swarm plot with matplotlib because I am looking to change the style, not just put the two together.
The last generic solution of ImportanceOfBeingErnest almost worked for me (Python 3.5.4) except that medians were not visible. Apparently, zorder of colored boxplots bodies hided the medians. Solution for me was to apply lower zorder to patches.
You need to change the
zorder
on theswarmplot
:The problem is that the boxplot consists of many different artists and because of the seaborn wrapping mechanism we cannot simply set the zorder of the complete boxplot to some higher number.
A first naive attempt would be to set the zorder of the swarmplot to zero. While this puts the swarmplot points behind the boxplot it also puts them behind the grid lines. This solution is thus only optimal, if no gridlines are used.
If gridlines are desired, we might set the zorder of the swarmplot to 1, such that it appears above the gridlines, and set the zorder of the boxplot to a high number. As mentionned above, this requires setting the zorder property to each of it's elements as
zorder=10
in theboxplot
call does not affect all the artists. Instead we need to use theboxprops
,whiskerprops
arguments to set the zorder properity for those as well.A final solution, which can be applied in general cases where no access at all is given to the artist properties is to loop through the axes artists and set zorder for them depending on whether they belong to the one or the other plot.