Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Black and white boxplots in Seaborn

I am trying to draw multiple black-and-white boxplots using Python's Seaborn package. By default the plots are using a color palette. I would like to draw them in solid black outline. The best I can come up with is:

# figure styles
sns.set_style('white')
sns.set_context('paper', font_scale=2)
plt.figure(figsize=(3, 5))
sns.set_style('ticks', {'axes.edgecolor': '0',  
                        'xtick.color': '0',
                        'ytick.color': '0'})

ax = sns.boxplot(x="test1", y="test2", data=dataset, color='white', width=.5)
sns.despine(offset=5, trim=True)
sns.plt.show()

Which produces something like:

enter image description here

I would like the box outlines to be black without any fill or changes in the color palette.

like image 885
denten Avatar asked Apr 16 '17 05:04

denten


People also ask

How do you change the color of a SNS boxplot?

This can be done by adding a palette argument inside the boxplot() function and giving it any predefined seaborn color palette value like “Set1”, “Set2”, “Paired”, “Set3” etc.

How do you change the color of a boxplot in Python?

To colorize the boxplot, you need to first use the patch_artist=True keyword to tell it that the boxes are patches and not just paths. Then you have two main options here: set the color via ... props keyword argument, e.g.

Can Boxplots be used for categorical data?

Box plots help visualize the distribution of quantitative values in a field. They are also valuable for comparisons across different categorical variables or identifying outliers, if either of those exist in a dataset.


2 Answers

You have to set edgecolor of every boxes and the use set_color for six lines (whiskers and median) associated with every box:

ax = sns.boxplot(x="day", y="total_bill", data=tips, color='white', width=.5, fliersize=0)

# iterate over boxes
for i,box in enumerate(ax.artists):
    box.set_edgecolor('black')
    box.set_facecolor('white')

    # iterate over whiskers and median lines
    for j in range(6*i,6*(i+1)):
         ax.lines[j].set_color('black')

If last cycle is applied for all artists and lines then it may be reduced to:

plt.setp(ax.artists, edgecolor = 'k', facecolor='w')
plt.setp(ax.lines, color='k')

where ax according to boxplot.

enter image description here

If you also need to set fliers' color follow this answer.

like image 178
Serenity Avatar answered Sep 22 '22 19:09

Serenity


I was just exploring this and it seems there is another way to do this now. Basically, there are the keywords boxprops, medianprops, whiskerprops and (you guessed it) capprops, all of which are dictionaries that may be passed to the boxplot func. I choose to define them above and then unpack them for readability:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

_to_plot = pd.DataFrame(
    {
     0: np.random.normal(0,1,100),
     1: np.random.normal(0,2,100),
     2: np.random.normal(0,-1,100),
     3: np.random.normal(0,-2,100)
     }
).melt()

PROPS = {
    'boxprops':{'facecolor':'none', 'edgecolor':'red'},
    'medianprops':{'color':'green'},
    'whiskerprops':{'color':'blue'},
    'capprops':{'color':'yellow'}
}

sns.boxplot(x='variable',y='value',
            data=_to_plot,
            showfliers=False,
            linewidth=0.75, 
            **PROPS)

enter image description here

like image 38
fffrost Avatar answered Sep 21 '22 19:09

fffrost