meforprez2032
meforprez2032

Reputation: 25

Custom Sorting in Plotly Express Icicle Visualizations

I am dealing with a dataset that has quarterly tasks, and I am trying to visualize it through a plotly express icicle chart. The way the data is structured is like this:

Objective Quarter Task Status Value
Finish Project A 1 Sort data Complete 1
Finish Project A 2 Clean data Complete 1
Finish Project A 2 Visualize plot Complete 1
Finish Project A 3 begin report In Progress 1
Finish Project A 3 Edit report Haven't started 1
Finish Project B 1 Email boss Haven't started 1

The problem is in the chart, even though the data is read in with this format, it sorts it based on the number of rows that correspond to that quarter. So in the plot, quarter 2 and 3 would be first for project a, with quarter 1 listed last. I want to flip that around so that it is in the order of the quarters, ie Q1->Q2->Q3->Q4, but I can't seem to find a great way to do that in plotly express. Below is my code that I am currently using:

fig = px.icicle(df, path=['Objective','Quarter','Task','Status'], values='Value', color='Status',
                color_discrete_map={'Haven't started':'red','In Progress':'yellow','Complete':'green'},
                maxdepth=3
    )

One other problem I have with this, is I am having it colored by the status column, but whenever a quarter has a mix of statuses that are not all one status (ie all being complete or in progress) it defaults to purple, which is basically unreadable for the rest of the cells. Is there a way I can change that default color, without losing the coloring by the status?

Upvotes: 0

Views: 815

Answers (1)

Rob Raymond
Rob Raymond

Reputation: 31206

import pandas as pd
import plotly.express as px

df = pd.DataFrame(
    [
        ["Finish Project A", 1, "Sort data", "Complete", 1],
        ["Finish Project A", 2, "Clean data", "Complete", 1],
        ["Finish Project A", 2, "Visualize plot", "Complete", 1],
        ["Finish Project A", 3, "begin report", "In Progress", 1],
        ["Finish Project A", 3, "Edit report", "Haven't started", 1],
        ["Finish Project B", 1, "Email boss", "Haven't started", 1],
    ],
    columns=["Objective", "Quarter", "Task", "Status", "Value"],
)

cm = {"Haven't started": "red", "In Progress": "yellow", "Complete": "green"}
fig = px.icicle(
    df,
    path=["Objective", "Quarter", "Task", "Status"],
    values="Value",
    color="Status",
    color_discrete_map=cm,
    maxdepth=3,
)

# required changes.  sort – Determines whether or not the sectors are reordered from largest to smallest.
# override color assigned to blocks with ambiguous status
fig.update_traces(
    sort=False,
    marker={
        "colors": tuple(
            c if c in cm.values() else "white" for c in fig.data[0]["marker"]["colors"]
        )
    },
)

Upvotes: 1

Related Questions