为了账号安全,请及时绑定邮箱和手机立即绑定

Plotly:如何对不同的痕迹使用变换颜色?

Plotly:如何对不同的痕迹使用变换颜色?

慕工程0101907 2024-01-16 10:30:35
我正在使用 pandas 的数据绘制图表。我有一个字典,其中键是日期,例如2020-10-26,值是 a pd.Dataframe,它有一个time列和 2 个数据列。.csv 格式的数据示例:for day, df in data.items():    day_name = datetime.datetime.strptime(day, "%Y-%m-%d").strftime("%A") # convert str to datetime, then to day    traces.append(go.Scatter(x=df["time"], y=df["SeriesA"], name=f"{day_name} SeriesA"))    traces.append(go.Scatter(x=df["time"], y=df["SeriesB"], name=f"{day_name} SeriesB"))有没有办法将每条线绘制为逐渐变化的色标中的不同颜色?理想情况下,我希望周一的所有痕迹都是不同的红色阴影,周二的每条痕迹都是不同的黄色阴影。我能想到的唯一方法是手动将十六进制值输入到列表中,然后为一周中的每一天建立一个索引。然后在绘制轨迹时执行以下操作:# If statement for every day of the weekif day_name == "Monday":    color = red_hex_values[monday_idx]    monday_idx += 1traces.append(go.Scatter(x=df["time"], y=df["SeriesA"], name=f"{day_name} SeriesA", color=color))但这似乎是一种非常混乱的方法。
查看完整描述

1 回答

?
aluckdog

TA贡献1847条经验 获得超7个赞

介绍

你的问题可以利用更好的焦点,因为它实际上是两个问题:

  1. 如何制作自定义色标

  2. 如何在绘图中使用平日的变换颜色。

我冒昧地或多或少地专门关注后一部分。尽管我将简要介绍前者的一些选项 - 如果您愿意,我们可以稍后再讨论。

回答

这是一个有趣的问题,我认为我已经通过对存储在字典中的值的指定色阶的循环迭代找到了一个可行的解决方案,daymap其中键是工作日名称:

daymap = {'Monday':cycle(px.colors.sequential.Reds), 
          'Tuesday':cycle(px.colors.sequential.Greens),
         }

px.colors.sequential.Reds 并且px.colors.sequential.Greens是内置的绘图色标。你特别要求黄色。但这是目前必须做的。

我已经进行了设置,以便weekday, color scale您设置的任何定义对都在图中分配,并且您选择不定义的所有工作日名称都被赋予您使用自定义函数指定的单个自定义颜色colfx()

def colfx(daymap, day_name, default_color):

    if day_name in daymap.keys():

        return next(daymap[day_name])

    else:

        return default_color

下面的完整代码片段以及 60 天的随机数据样本将使用上述规范以及其他一些细节生成下面的图 1。


地块1

https://img1.sycdn.imooc.com/65a5ea7b0001c84106460273.jpg

图 2 是通过在 中添加另一个键、值对daymap并将默认颜色更改为colfx()来生成的'rgba(150,150,150, 0.2)'。我发现使用rgba颜色作为默认颜色很实用,因为上一个术语0.2可以让您轻松设置颜色的不透明度。

地块2

https://img1.sycdn.imooc.com/65a5ea8a0001901406510268.jpg

完整代码

import pandas as pd

import numpy as np

import plotly.graph_objects as go

import plotly.express as px

from itertools import cycle


# data

obs = 60

dates = pd.date_range(start='2020-01-01', periods=obs)

random = np.random.RandomState(0)

df = pd.DataFrame({'data': np.random.uniform(low=0, high=100, size=obs).tolist()}, index=dates)


# custom function to assign next color in a color sequence

# for each new day defined in the dict daymap

def colfx(daymap, day_name, default_color):

    if day_name in daymap.keys():

        return next(daymap[day_name])

    else:

        return default_color


# color specifications for weekday

daymap = {'Monday':cycle(px.colors.sequential.Reds),

           'Tuesday':cycle(px.colors.sequential.Greens),

           'Friday':cycle(px.colors.sequential.thermal)

         }

    

# container for weekday names added to the figure legend

# if the weekday names has ALREADY been added to the legend,

# then no further additions are made

fignames = []


fig=go.Figure()

for row in df.iterrows():

    day_name=row[0].strftime("%A")

    fignames = [d.name for d in fig.data]

    fig.add_bar(x=[row[0]],

                y=[row[1]['data']],

                marker_color=colfx(daymap=daymap, day_name = day_name, default_color='rgba(150,150,150, 0.2)'),

                name=day_name,

                legendgroup = day_name,

                showlegend = False if day_name in fignames else True

               )

    

fig.show()



查看完整回答
反对 回复 2024-01-16
  • 1 回答
  • 0 关注
  • 78 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信