nim_10
nim_10

Reputation: 496

Plotly: how to use two sets of colors in plotly timeline figure?

I have plotted a time series bar plot with two labels in “y” axis using plotly express. The “color” label is based on a third category. Here is a snapshot of simplified code and output:

import pandas as pd
import datetime
import plotly.express as px

df = pd.DataFrame(dict({
    'beginTime': [
        datetime.datetime.strptime('1/1/2008 1:00:15', '%m/%d/%Y %H:%M:%S'),
        datetime.datetime.strptime('1/1/2008 1:15:15', '%m/%d/%Y %H:%M:%S'),
        datetime.datetime.strptime('1/1/2008 2:00:15', '%m/%d/%Y %H:%M:%S'),
        datetime.datetime.strptime('1/1/2008 1:00:15', '%m/%d/%Y %H:%M:%S'),
        datetime.datetime.strptime('1/1/2008 1:02:15', '%m/%d/%Y %H:%M:%S'),
        datetime.datetime.strptime('1/1/2008 1:20:15', '%m/%d/%Y %H:%M:%S'),
    ],
    'endTime': [
        datetime.datetime.strptime('1/1/2008 1:10:15', '%m/%d/%Y %H:%M:%S'),
        datetime.datetime.strptime('1/1/2008 1:35:15', '%m/%d/%Y %H:%M:%S'),
        datetime.datetime.strptime('1/1/2008 2:07:15', '%m/%d/%Y %H:%M:%S'),
        datetime.datetime.strptime('1/1/2008 1:8:15', '%m/%d/%Y %H:%M:%S'),
        datetime.datetime.strptime('1/1/2008 1:12:15', '%m/%d/%Y %H:%M:%S'),
        datetime.datetime.strptime('1/1/2008 1:59:15', '%m/%d/%Y %H:%M:%S'),
    ],
    'type': ['1', '1', '1', '2', '2', '2'],
    'activity': ['competition1', 'competition1', 'competition1', 'competition2', 'competition2', 'competition2'],
    'label': ['eat', 'sleep', 'write', 'write', 'code', 'sleep']
}
))
fig = px.timeline(df, x_start="beginTime", x_end="endTime", y="type", color='label')
fig.show()

enter image description here

My question is,

  1. how can I apply two seperate sets of colors for each of the labels in “y” axis (so the colors do not overlap)?
  2. or how can two sets of "color" map applied into one timeline plot?

Upvotes: 0

Views: 1035

Answers (1)

Rob Raymond
Rob Raymond

Reputation: 31236

  • you can create traces for each y with different color sequence for each y
  • integrate these traces using graph objects
import pandas as pd
import datetime
import plotly.express as px
import inspect
import plotly.graph_objects as go

df = pd.DataFrame(
    dict(
        {
            "beginTime": [
                datetime.datetime.strptime("1/1/2008 1:00:15", "%m/%d/%Y %H:%M:%S"),
                datetime.datetime.strptime("1/1/2008 1:15:15", "%m/%d/%Y %H:%M:%S"),
                datetime.datetime.strptime("1/1/2008 2:00:15", "%m/%d/%Y %H:%M:%S"),
                datetime.datetime.strptime("1/1/2008 1:00:15", "%m/%d/%Y %H:%M:%S"),
                datetime.datetime.strptime("1/1/2008 1:02:15", "%m/%d/%Y %H:%M:%S"),
                datetime.datetime.strptime("1/1/2008 1:20:15", "%m/%d/%Y %H:%M:%S"),
            ],
            "endTime": [
                datetime.datetime.strptime("1/1/2008 1:10:15", "%m/%d/%Y %H:%M:%S"),
                datetime.datetime.strptime("1/1/2008 1:35:15", "%m/%d/%Y %H:%M:%S"),
                datetime.datetime.strptime("1/1/2008 2:07:15", "%m/%d/%Y %H:%M:%S"),
                datetime.datetime.strptime("1/1/2008 1:8:15", "%m/%d/%Y %H:%M:%S"),
                datetime.datetime.strptime("1/1/2008 1:12:15", "%m/%d/%Y %H:%M:%S"),
                datetime.datetime.strptime("1/1/2008 1:59:15", "%m/%d/%Y %H:%M:%S"),
            ],
            "type": ["1", "1", "1", "2", "2", "2"],
            "activity": [
                "competition1",
                "competition1",
                "competition1",
                "competition2",
                "competition2",
                "competition2",
            ],
            "label": ["eat", "sleep", "write", "write", "code", "sleep"],
        }
    )
)

# create a figure for each y with different color sequence
figs = [
    px.timeline(
        g[1],
        x_start="beginTime",
        x_end="endTime",
        y="type",
        color="label",
        color_discrete_sequence={a:b for a,b in inspect.getmembers(px.colors.qualitative)}[cs],
    )
    for g,cs in zip(df.groupby("type"), ["Alphabet","G10"])
]

# integrate it
go.Figure(data=[d for f in figs for d in f.data ], layout=figs[0].layout)

enter image description here

Upvotes: 2

Related Questions