Plotly marker line color based on dataframe column category

Question:

I have the following example df:

   col1  col2 col3
0     1    10    C
1     2    15    A
2     3    20    A
3     4    25    A
4     5    30    B
5     6    35    B
6     7    40    B
7     8    45    B
8     9    50    B
9    10    55    B

And here is my simple code for the scatter plot below:

import plotly.express as px
import pandas aspd

df = pd.DataFrame({'col1':[1,2,3,4,5,6,7,8,9,10],
                'col2':[10,15,20,25,30,35,40,45,50,55],
                'col3':['C','A','A','A','B','B','B','B','B','B']})
fig = px.scatter(df, x='col1', y='col2', color='col3')
fig.update_traces(marker=dict(size=12))        
fig.show()

The plot separates the colors of markers from col3, however, I would like to make a plot with markers that are not filled with any color, but rather have the marker line colors from col3.

enter image description here

Asked By: serdar_bay

||

Answers:

As you mentioned, I believe you are okay using plotly.graph_objects.

Here, I am using map to assign a different color for each unique value in df.col3 (A, B, C). While plotting the scatter plot, you can set the marker fill color to transparent by using the rgba (where a = alpha = transparency) to 0, meaning fully transparent

Then, using the line (which is the border line to map to the color you want – in this case the col3.map(colors). You can also set the width of the edge line… Hope this is what you are looking for…

df = pd.DataFrame({'col1':[1,2,3,4,5,6,7,8,9,10],
                'col2':[10,15,20,25,30,35,40,45,50,55],
                'col3':['C','A','A','A','B','B','B','B','B','B']})

import plotly.graph_objects as go
colors={'A':'red', 'B':'blue', 'C':'green'}
fig = go.Figure()
fig.add_trace(go.Scatter(x=df.col1, y=df.col2, 
                         marker=dict(size=12, color='rgba(255,255,255,0)',
                                     line=dict(color=df['col3'].map(colors), width=3))))

Output Plot

enter image description here

OPTION 2

Here, I have modified the code so that the colors dictionary now picks up all the unique values from the input dataframe-col3. As we don’t know the count of the unique values, I am using a colormap (plasma) to set the colors for the lines. You do need to add the colorscale to this. You can of course choose a colormap to your liking. Hope this helps.

df = pd.DataFrame({'col1':[1,2,3,4,5,6,7,8,9,10],
                'col2':[10,15,20,25,30,35,40,45,50,55],
                'col3':['C','A','A','A','B','B','B','B','B','B']})

colors=dict(zip(df.col3.unique(), np.linspace(0,1,df.col3.nunique())))

import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Scatter(x=df.col1, y=df.col2, 
                         marker=dict(size=12, color='rgba(255,255,255,0)', 
                                     line=dict(color=df['col3'].map(colors), colorscale='plasma', width=3))))

Output Plot 2

enter image description here

Answered By: Redox

If you are in fact happy with what your example code does with regards to color attribution based on 'col3':['C','A','A','A','B','B','B','B','B','B'], then you can just add the following line to your snippet to produce circles with the same colors as the original markers, and no markers. In other words, holes in the middle:

fig.for_each_trace(lambda t: t.update(marker_line_color = t.marker.color, marker_line_width = 15,
                                  marker_color = 'rgba(0,0,0,0)'))

Plot:

enter image description here

Complete code:

import pandas as pd
import plotly.express as px
import numpy as np

df = pd.DataFrame({'col1':[1,2,3,4,5,6,7,8,9,10],

                'col2':[10,15,20,25,30,35,40,45,50,55],
                'col3':['C','A','A','A','B','B','B','B','B','B']})


fig = px.scatter(df, x='col1', y='col2', color='col3')
fig.update_traces(marker=dict(size=8))        
fig.show()

fig.for_each_trace(lambda t: t.update(marker_line_color = t.marker.color, marker_line_width = 15,
                                      marker_color = 'rgba(0,0,0,0)'))
fig.show()
Answered By: vestland
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.