首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从Plotly Color Scale访问颜色

从Plotly Color Scale访问颜色
EN

Stack Overflow用户
提问于 2020-07-03 14:58:19
回答 3查看 1.8K关注 0票数 7

在Plotly中有没有一种方法可以访问其范围内任何值的色彩映射表颜色?

我知道我可以访问colourscale的定义颜色。

代码语言:javascript
运行
复制
plotly.colors.PLOTLY_SCALES["Viridis"]

但是我无法找到如何访问中间/内插值。

Matplotlib中的等价物显示为in this questioncolorlover库中也有解决类似问题的another question,但这两个都不是很好的解决方案。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-06-10 06:11:07

这个答案扩展了Adam提供的已经很好的答案。特别是,它处理了普洛特利色标的不一致性。

在Plotly中,您可以通过编写colorscale="name_of_the_colorscale"来指定内置的色标。这表明Plotly已经有了一个内置的工具,可以以某种方式将色标转换为合适的值,并且能够处理这些不一致。通过搜索Plotly的源代码,我们找到了有用的ColorscaleValidator类。让我们看看如何使用它:

代码语言:javascript
运行
复制
def get_color(colorscale_name, loc):
    from _plotly_utils.basevalidators import ColorscaleValidator
    # first parameter: Name of the property being validated
    # second parameter: a string, doesn't really matter in our use case
    cv = ColorscaleValidator("colorscale", "")
    # colorscale will be a list of lists: [[loc1, "rgb1"], [loc2, "rgb2"], ...] 
    colorscale = cv.validate_coerce(colorscale_name)
    
    if hasattr(loc, "__iter__"):
        return [get_continuous_color(colorscale, x) for x in loc]
    return get_continuous_color(colorscale, loc)
        

# Identical to Adam's answer
import plotly.colors
from PIL import ImageColor

def get_continuous_color(colorscale, intermed):
    """
    Plotly continuous colorscales assign colors to the range [0, 1]. This function computes the intermediate
    color for any value in that range.

    Plotly doesn't make the colorscales directly accessible in a common format.
    Some are ready to use:
    
        colorscale = plotly.colors.PLOTLY_SCALES["Greens"]

    Others are just swatches that need to be constructed into a colorscale:

        viridis_colors, scale = plotly.colors.convert_colors_to_same_type(plotly.colors.sequential.Viridis)
        colorscale = plotly.colors.make_colorscale(viridis_colors, scale=scale)

    :param colorscale: A plotly continuous colorscale defined with RGB string colors.
    :param intermed: value in the range [0, 1]
    :return: color in rgb string format
    :rtype: str
    """
    if len(colorscale) < 1:
        raise ValueError("colorscale must have at least one color")

    hex_to_rgb = lambda c: "rgb" + str(ImageColor.getcolor(c, "RGB"))

    if intermed <= 0 or len(colorscale) == 1:
        c = colorscale[0][1]
        return c if c[0] != "#" else hex_to_rgb(c)
    if intermed >= 1:
        c = colorscale[-1][1]
        return c if c[0] != "#" else hex_to_rgb(c)

    for cutoff, color in colorscale:
        if intermed > cutoff:
            low_cutoff, low_color = cutoff, color
        else:
            high_cutoff, high_color = cutoff, color
            break

    if (low_color[0] == "#") or (high_color[0] == "#"):
        # some color scale names (such as cividis) returns:
        # [[loc1, "hex1"], [loc2, "hex2"], ...]
        low_color = hex_to_rgb(low_color)
        high_color = hex_to_rgb(high_color)

    return plotly.colors.find_intermediate_color(
        lowcolor=low_color,
        highcolor=high_color,
        intermed=((intermed - low_cutoff) / (high_cutoff - low_cutoff)),
        colortype="rgb",
    )

此时,您所要做的就是:

代码语言:javascript
运行
复制
get_color("phase", 0.5)
# 'rgb(123.99999999999999, 112.00000000000001, 236.0)'

import numpy as np
get_color("phase", np.linspace(0, 1, 256))
# ['rgb(167, 119, 12)',
#  'rgb(168.2941176470588, 118.0078431372549, 13.68235294117647)',
#  ...

编辑:改进以处理特殊情况。

票数 3
EN

Stack Overflow用户

发布于 2020-11-03 09:37:30

Plotly似乎没有这样的方法,所以我写了一个:

代码语言:javascript
运行
复制
import plotly.colors

def get_continuous_color(colorscale, intermed):
    """
    Plotly continuous colorscales assign colors to the range [0, 1]. This function computes the intermediate
    color for any value in that range.

    Plotly doesn't make the colorscales directly accessible in a common format.
    Some are ready to use:
    
        colorscale = plotly.colors.PLOTLY_SCALES["Greens"]

    Others are just swatches that need to be constructed into a colorscale:

        viridis_colors, scale = plotly.colors.convert_colors_to_same_type(plotly.colors.sequential.Viridis)
        colorscale = plotly.colors.make_colorscale(viridis_colors, scale=scale)

    :param colorscale: A plotly continuous colorscale defined with RGB string colors.
    :param intermed: value in the range [0, 1]
    :return: color in rgb string format
    :rtype: str
    """
    if len(colorscale) < 1:
        raise ValueError("colorscale must have at least one color")

    if intermed <= 0 or len(colorscale) == 1:
        return colorscale[0][1]
    if intermed >= 1:
        return colorscale[-1][1]

    for cutoff, color in colorscale:
        if intermed > cutoff:
            low_cutoff, low_color = cutoff, color
        else:
            high_cutoff, high_color = cutoff, color
            break

    # noinspection PyUnboundLocalVariable
    return plotly.colors.find_intermediate_color(
        lowcolor=low_color, highcolor=high_color,
        intermed=((intermed - low_cutoff) / (high_cutoff - low_cutoff)),
        colortype="rgb")

挑战在于,内置的Plotly色标并不总是暴露出来的。有些已定义为色标,另一些仅定义为必须首先转换为色标的色样列表。

Viridis colorscale是使用十六进制值定义的,这是Plotly颜色处理方法不喜欢的,因此从样例中构建它是最容易的,如下所示:

代码语言:javascript
运行
复制
viridis_colors, _ = plotly.colors.convert_colors_to_same_type(plotly.colors.sequential.Viridis)
colorscale = plotly.colors.make_colorscale(viridis_colors)

get_continuous_color(colorscale, intermed=0.25)
# rgb(58.75, 80.75, 138.25)
票数 8
EN

Stack Overflow用户

发布于 2020-07-03 17:53:06

官方的参考资料解释说。Here

代码语言:javascript
运行
复制
import plotly.express as px

print(px.colors.sequential.Viridis)
['#440154', '#482878', '#3e4989', '#31688e', '#26828e', '#1f9e89', '#35b779', '#6ece58', '#b5de2b', '#fde725']

print(px.colors.sequential.Viridis[0])
#440154
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62710057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档