Plotly: How to set a varying marker opacity, but keep the same outline color for all markers?

Viewed 2394

I'm trying to plat marker where maker opacity is changed by some vector.

But marker edge color opacity is constant.

   fig.add_trace(go.Scatter(x=real.index, y=real['some_value'],
                             mode='markers',
                             marker={'opacity': real['another value'],
                                     'color':'green',
                                     'size':10,
                                     'line':dict(width=1,
                                                 color='rgba(165,42,42,1)')}
                            ))

It can be seen in plot below, that the marker edge color opacity, is changed together with color opacity of the marker filling.

My purpose is to keep line (marker edge ) opacity constant.

enter image description here

NOTE: this question doesn't answer the question:

plotly.py: change line opacity, leave markers opaque

1 Answers

You can easily rescale a pandas series between 0 and 1 and use that as an argument in rgba(red,green,blue,opacity) like color='rgba(100,0,255,'+opac+')' where opac is some opacity between 0 and 1 for a certain marker in your figure. The color property of the markers is unique for any go.Scatter(), so you'll have to add a unique trace for each point. Then, at the same time, you can set color (and opacity if you should feel so inclined) for the outline of the marker using marker=dict(line=dict(color='rgba(100,0,255,1)'))

In the figure below, I've set the outline color as 'rgba(100,0,255,1)', and the opacity of the marker fill as varying according to the logic above. This way, the highest values will appear as a completely "filled" marker:

enter image description here

But you can also set a more clearly defined line using, for example, line=dict(color='rgba(0,0,0,1)', width = 2) to get something like this:

enter image description here

Now you can play around with all the rgba arguments to find a color to your liking.

Complete code:

# imports
import plotly.graph_objects as go
import pandas as pd
import numpy as np

# sample data in the form of an hourlt
np.random.seed(1234)
tseries = pd.date_range("01.01.2020", "01.04.2020", freq="H")
data = np.random.randint(-100, 100, size=(len(tseries), 3))
df = pd.DataFrame(data=data)
df.columns=list('ABC')
df['C_scaled'] = df['C'].max()/df['C']
df['C_scaled'] = (df['C']-df['C'].min())/(df['C'].max()-df['C'].min())

df = df.sort_values(by=['C_scaled'], ascending=False)

fig=go.Figure()

for ix in df.index:
    d = df.iloc[ix]
    opac = str(d['C_scaled'])
    fig.add_trace(go.Scatter(x=[d['A']], y=[d['B']], showlegend=False,
                             marker=dict(size = 14, color='rgba(100,0,255,'+opac+')',
                                         line=dict(color='rgba(0,0,0,1)', width = 2)))
                            )
    
fig.show()

Edit: Hoverinfo side-effects

Just include the following to edit the hoverinfo so that x and y values always are shown on hover to the closeset values:

fig.update_layout(hovermode="x")
fig.update_traces(hoverinfo = 'x+y')

Related