Black Lives Matter. Please consider donating to Black Girls Code today. # Conditional formatting of scatterplot markers

Problem:
I have a data set with `x` and `y` value pairs, plus `lower_limit` and `upper_limit` values for `y`.

I want to plot `x` vs. `y` in a plot.ly scatter plot, and colour the marker in green if `lower_limit``y``upper_limit`, else in red.

I know that I could use 2 traces, or add a `color` column in the DataFrame. However, I’d like to generate these colour on the fly and use one trace only.

Example:
Consider this data set:

``````   x   y  lower_limit  upper_limit
0  1  13           10           15
1  2  13           15           20
2  3  17           15           20
``````

The first marker (`x`=1, `y`=13) should be green, because `lower_limit``y``upper_limit` (10 ≤ 13 ≤ 15), just like the third one.
However the second should be red, because `y` < `lower_limit`.

MWE:

``````import pandas as pd
import plotly.graph_objs as go
import plotly.plotly as py
import plotly.offline as po

data = [
[1, 13, 10, 15],
[2, 13, 15, 20],
[3, 17, 15, 20]
]

df = pd.DataFrame(
data,
columns=['x', 'y', 'lower_limit', 'upper_limit']
)

trace = go.Scatter(
x=df['x'],
y=df['y'],
mode='markers',
marker=dict(
size=42,
# I want the color to be green if
# lower_limit ≤ y ≤ upper_limit
# else red
color='green',
)
)

po.plot([trace])
``````

Hi @ebosi,

Here’s an approach using pandas to compute the inequalities and a colorscale to specify the colors.

``````import pandas as pd
import plotly.graph_objs as go
import plotly.plotly as py
import plotly.offline as po

data = [
[1, 13, 10, 15],
[2, 13, 15, 20],
[3, 17, 15, 20]
]

df = pd.DataFrame(
data,
columns=['x', 'y', 'lower_limit', 'upper_limit']
)

trace = go.Scatter(
x=df['x'],
y=df['y'],
mode='markers',
marker=dict(
size=42,
# I want the color to be green if
# lower_limit ≤ y ≤ upper_limit
# else red
color=(
(df.lower_limit < df.y) &
(df.y < df.upper_limit)
).astype('int'),
colorscale=[[0, 'red'], [1, 'green']]
)
)

po.plot([trace])
``````

Hope that helps!
-Jon

2 Likes

Sound brilliant, thank you!