'plotly.py: change line opacity, leave markers opaque

Is it possible to change the line opacity but not the marker opacity? I found that I can set the opacity of the entire line including markers (opacity = .5) and the one of the marker (e.g. marker={"opacity":1}).

As shown in this example:

import plotly
import plotly.graph_objs as go
plotly.offline.init_notebook_mode(connected=True)  # I'm running in a jupyter notebook

x = np.arange(0,10)
ys = [np.random.rand(10) for _ in range(3)]

lines = []
for y in ys:
    line = go.Scatter(x=x, y=y, mode="markers+lines", opacity=.5, marker={'symbol': 'x', 'size': "15", "opacity":1})
    lines.append(line)           
fig = go.Figure(
    data=lines,
    layout=go.Layout(showlegend=True)
)
plotly.offline.iplot(fig)

See result here: current result

My problem is the following: My data points are important, the lines are just visual aid. I want to make the lines .5-opaque but have the markers fully opaque.
However, when I set opacity=.5, marker={'opacity':1} the opacity of the marker is also reduced. (I believe that the marker-opacity is defined in the range [0, line-opacity].

Is there any way I can get the colour of the line and adjust its opacity (perhaps even after creating the line, but before plotting it). I know that I could create two traces, one with the points and one with the lines. However, I would like them to be the same colour without having to manually specify the colours. (The number of traces is varying, so I prefer sticking to the standard mechanism that assigns the different colours)

EDIT: My current solution is to set the line-width to 0.5 so it looks better, but obviously this solution works for me and might not be useful to people who want bold and less opaque lines.

EDIT: Github issue concerning this problem/feature request/behaviour: https://github.com/plotly/plotly.js/issues/2684



Solution 1:[1]

TL;DR - one could use: line=dict(color='rgba(255, 0, 0, 0.5)') - example from @david Parks

Line objects don't have opacity attributes but you can assign colors using RGBA and set the alpha. You have to assign a color for the markers using RGBA or it will inherit from the line.

In the following example, I create three random lines with random colors. I then assign the same color to the markers and lines but use string concatenation to change the opacity on the lines versus the markers. The markers will be fully opaque while the lines will be 80% transparent.

import plotly
import numpy as np
import plotly.graph_objs as go

plotly.offline.init_notebook_mode(connected=True)
x = np.arange(0,10)
ys = [np.random.rand(10) for _ in range(3)]

lines = []
dots = []
for y in ys:
    my_color = ('rgba('+str(np.random.randint(0, high = 256))+','+
                str(np.random.randint(0, high = 256))+','+
                str(np.random.randint(0, high = 256)))
    # my_color := "rgba( 143, 82, 244"
    line = go.Scatter(
            x=x, 
            y=y, 
            mode="lines+markers", 
            marker={ 
                    'symbol': 'x', 
                    'size': "15", 
                    'color':my_color+',1)' # "rgba( 143, 82, 244,1)"
                    },
            line={
                "color":my_color+',0.2)'
            })
    lines.append(line)  

fig = go.Figure(
    data=lines,
    layout=go.Layout(showlegend=True)
)
plotly.offline.iplot(fig)

enter image description here

Solution 2:[2]

Here is the link of the best answer I found : https://github.com/plotly/plotly.js/issues/2684#issuecomment-641023041 , where you use a function to convert color under hex format to rgba format that enables defining alpha opacity on last argument as mentioned on other answers.

def hex_to_rgba(h, alpha):
    '''
    converts color value in hex format to rgba format with alpha transparency
    '''
    return tuple([int(h.lstrip('#')[i:i+2], 16) for i in (0, 2, 4)] + [alpha])

Then you can use it with

import plotly.graph_objects as go
import plotly.express as px
COLORS = px.colors.qualitative.D3

hex_color = COLORS[0]  # Blue

traces = [
    go.Scatter(
        x=[0, 1],
        y=[0, 1],
        name='Identity line',
        showlegend=False,
        line=dict(
            color='rgba' + str(hex_to_rgba(
                h=hex_color,
                alpha=0.25
            )),
            width=2,
            dash='dash'
        ),
        marker=dict(
            size=7,
            symbol='circle',
            color='rgba' + str(hex_to_rgba(
                h=hex_color,
                alpha=1
            ))
        ),
    )
]

layout = go.Layout(template='simple_white')
figure = go.Figure(data=traces, layout=layout)
figure.show()

So here for blue color : hex format is '#1F77B4' and rgba format is 'rgba(31, 119, 180, 0.5)'

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2