# Applying a custom color scale with Plotly Boxplots

Jul 23, 2018 · 3 min read

I was recently asked by my boss to apply a color scale to a series of Plotly Box plots I was working on for a Dash application. The notion was to plot multiple box plots on the same graph and have each box plot be darker or lighter based on it’s distance from the overall median in the dataset.

# The problem

The issue here is that Plotly only supports color scales for heatmaps, scatter plots & contour plots.

I will demonstrate the default behavior by plotting some generated data for Canucks players `+/- per game all time` as follows:

Note: Complete code at the end of the post

The dashed green line represents the `NHL league average +/- per game at +2.0`, what my boss wanted was to color each box plot darker or lighter based on how far away `each players median +/- `value was from the `league average` .

# The solution

Given that I was already in a Python environment, I chose to use the `colormap` & `colormap normalizer` features from the Matplotlib Python module.

First step was to import Matplotlib:

`import matplotlib.pyplot as pltimport matplotlibimport pandas as pd`

Then determine the `min`and `max`values in the dataset:

`x_data = ['Henrik Sedin', 'Daniel Sedin',          'Brock Boeser', 'Elias Pettersen',          'Bo Horvat', 'Pavel Bure',]# Generate random datay0 = np.random.randn(50)+4y1 = np.random.randn(50)+4y2 = np.random.randn(50)+2y3 = np.random.randn(50)+2y4 = np.random.randn(50)+1y5 = np.random.randn(50)+3y_data = [y0,y1,y2,y3,y4,y5]df = pd.DataFrame(y_data)vmin, vmax = df.min().min(), df.max().max()`

Initialize the Matplotlib cmap & normalizer:

`norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)cmap = matplotlib.cm.get_cmap('GnBu') # green to blue color way`

Find the median of each `y_data` and use the normalizer to map it to an appropriate color based on the median value:

`for xd, yd in zip(x_data, y_data):                median = np.median(yd) # find the median        color = 'rgb' + str(cmap(norm(median))[0:3]) # normalize                traces.append(go.Box(            y=yd,            name=xd,            boxpoints='all',            jitter=0.5,            whiskerwidth=0.2,            fillcolor=color,      # add the box plot color            marker=dict(                size=2,            ),            line=dict(width=1)        ))`

# VIOLA!

The resulting plot will render a darker `fillcolor`the further positive the `players median +/-` is from the `league average` and vice versa.

# BONUS

Here is the complete code to get the result above:

`from plotly import __version__from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplotinit_notebook_mode(connected=True)import plotly.graph_objs as goimport numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport matplotlibx_data = ['Henrik Sedin', 'Daniel Sedin',          'Brock Boeser', 'Elias Pettersen',          'Bo Horvat', 'Pavel Bure',]y0 = np.random.randn(50)+4y1 = np.random.randn(50)+4y2 = np.random.randn(50)+2y3 = np.random.randn(50)+2y4 = np.random.randn(50)+1y5 = np.random.randn(50)+3y_data = [y0,y1,y2,y3,y4,y5]traces = []df = pd.DataFrame(y_data)vmin, vmax = df.min().min(), df.max().max()norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)cmap = matplotlib.cm.get_cmap('GnBu')for xd, yd in zip(x_data, y_data):        median = np.median(yd)        color = 'rgb' + str(cmap(norm(median))[0:3])                traces.append(go.Box(            y=yd,            name=xd,            boxpoints='all',            jitter=0.5,            whiskerwidth=0.2,            fillcolor=color,            marker=dict(                size=2,                color='rgb(0, 0, 0)'            ),            line=dict(width=1),        ))layout = go.Layout(    title='Canucks all time +/- per game',    yaxis=dict(        autorange=True,        showgrid=True,        zeroline=True,        dtick=5,        gridcolor='rgb(255, 255, 255)',        gridwidth=1,        zerolinecolor='rgb(255, 255, 255)',        zerolinewidth=2,    ),    margin=dict(        l=40,        r=30,        b=80,        t=100,    ),    paper_bgcolor='rgb(243, 243, 243)',    plot_bgcolor='rgb(243, 243, 243)',    showlegend=False,    shapes= [{      'type': 'line',      'x0': -1,      'y0': 2,      'x1': 6,      'y1': 2,      'line': {        'color': 'rgb(50, 171, 96)',        'width': 4,        'dash': 'dashdot'      }    }])fig = go.Figure(data=traces, layout=layout)iplot(fig)`

Written by

## More From Medium

#### Also tagged Plotly

Feb 6 · 4 min read

#### Also tagged Plotly

Feb 10 · 7 min read