plotly.py:如何改变线条透明度并保留标记不透明?

23

有没有可能只改变线的透明度而不改变标记的透明度呢? 我发现可以设置整条线(包括标记)的透明度(opacity=.5),也可以设置单个标记的透明度(例如marker={"opacity":1})。

就像这个例子所示:

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)

在此查看结果:current result

我的问题如下:数据点很重要,线只是视觉辅助工具。我想让线的不透明度为0.5但标记完全不透明。
然而,当我设置 opacity=.5, marker={'opacity':1} 时,标记的不透明度也会降低。(我相信标记的不透明度定义在范围[0,线不透明度]内)。

有没有办法获取线条的颜色并调整其不透明度(甚至在创建线条之后,在绘制它之前调整)。 我知道我可以创建两个轨迹,一个带有点,一个带有线。但是,我希望它们的颜色相同,而不必手动指定颜色。(轨迹数量是变化的,因此我更喜欢坚持分配不同颜色的标准机制)

编辑:我的当前解决方案是将线宽设置为0.5,这样它看起来更好,但显然这个解决方案对我有效,可能对想要粗体和不那么透明的线条的人没有用。

编辑:关于此问题/功能请求/行为的 Github 问题: https://github.com/plotly/plotly.js/issues/2684


似乎是一个错误,因为父属性仍然被更新到子属性,即使子属性已经设置了,你能否向Plotly团队提出此问题?您是否对使用两个跟踪解决方案感兴趣,一个用于标记,另一个用于线条? - Naren Murali
@NarenMurali 我把这两个跟踪视为备份。我发帖是因为我对“官方”解决方案感兴趣。 - stklik
1
作为备选方案,请在此处提出问题票据这里,他们可能会给一些建议,但我认为如果他们指定了标记的不透明度,应该忽略轨迹的不透明度! - Naren Murali
2个回答

26

TL;DR - 可以使用以下语句:

line=dict(color='rgba(255, 0, 0, 0.5)')

(来自 @david Parks 的示例)

线对象没有 opacity 属性,但可以使用 RGBA 分配颜色并设置 alpha 值。如果不使用 RGBAmarkers 分配颜色,则会继承自线。

在以下示例中,我创建了三条随机的线,并分配了随机颜色。然后,将相同的颜色分配给 markers 和 lines,但使用字符串拼接更改线与标记之间的透明度。标记将完全不透明,而线将是 80% 不透明。

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)

在这里输入图片描述


1
你的解决方案对我无效(至少是对我而言)。 文档中没有提到opacity作为线条属性,尝试设置它会导致PlotlyDictKeyError: 'opacity'不允许在'line'中使用 - stklik
1
@iwileczek 这个方法可行,但是标记的颜色和线条不同。在获取所选线条颜色后,通过应用 rgba 转换来进行后处理可能会很有趣。还要查看 Github Issue,我请求官方功能而无需手动设置通用颜色。 - stklik
你可以通过连接字符串使它们相同。请查看编辑。 - lwileczek
2
一个简单的例子:line=dict(color='rgba(255, 0, 0, 0.5)') 创建了一条半透明的红色线。 - David Parks

5
这是我找到的最佳答案链接: https://github.com/plotly/plotly.js/issues/2684#issuecomment-641023041 其中,您可以使用一个函数将十六进制格式的颜色转换为rgba格式,从而在最后一个参数上定义alpha不透明度,正如其他答案中所提到的那样。
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])

然后你可以使用它与

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()

这里是蓝色的颜色代码:十六进制格式为'#1F77B4'RGBA格式为'rgba(31, 119, 180, 0.5)'


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接