Search code examples
pythonpandasplotly-python

Define plotly colours as column in dataframe


I'm plotting several different graphs in plotly which I want to have a consistent custom colour scheme. So I'm defining a colour column in the pandas dataframes which I'm plotting, but I can't seem to get plotly to use the colours in that column.

import pandas as pd
import pltly.express as px

colours = {'category one': '#0e4f53', 'category two': '#001122', 'category three': '#334455'}
colour_df = pd.DataFrame(list(colours.items()), columns=['category', 'colour'])

# data_df has a 'category' column overlapping with the colour definitions
df = pd.merge(data_df, colour_df, on='category')
fig = px.pie(df, values='values', names='category')

Things I've tried so far to get the pie segments to match the colour defined in colours (as arguments in px.pie():

color='colour' # using the column name of df
color_discrete_map=colours
color_discrete_map=df['colours']

None of these have worked. Using color_discrete_sequence=list(colours.values()) does work, but that's not useful if I want to match across categories across different dataframes, which may not be ordered in the same way.

The plotly documentation says I can use a column name for the color argument, but I don't know why it's not using the hex values in the column to set the colour.


Solution

  • Is this what you're looking for?

    
    fig = px.pie(
        df,
        values='values',
        names='category',
        color='category',
        color_discrete_sequence=df['colour'],
        color_discrete_map=dict(zip(df['category'], df['colour']))
    )
    fig.show()
    
    

    Output:

    enter image description here

    If so, change the value from the color parameter to your category column name, and pass to the color_discrete_map as a dictionary mapping each color to their respective category (key should be the categories and value colors).

    Full Example

    import pandas as pd
    import plotly.express as px
    
    colours = {
        "category one": "#0e4f53",
        "category two": "#001122",
        "category three": "#334455",
    }
    colour_df = pd.DataFrame(list(colours.items()), columns=["category", "colour"])
    data_df = pd.DataFrame(
        {
            "category": [
                "category one",
                "category two",
                "category one",
                "category three",
                "category two",
                "category two",
            ],
            "values": [40, 20, 10, 90, 50, 50],
        }
    )
    df = pd.merge(data_df, colour_df, on="category")  # .sort_values('values')
    fig = px.pie(
        df,
        values="values",
        names="category",
        color="category",
        color_discrete_sequence=df["colour"],
        color_discrete_map=dict(zip(df["category"], df["colour"])),
    )
    fig.show()