pythonplotlyvisualizationplotly-dashplotly-python

Create a Stacked Bar Chart with different colours using a custom template in Plotly Python


I am using Plotly to create a Stacked Bar Chart with different colors I have defined myself in mytemplate. The problem is that the colors go to the same x and not the same bars like I want them to. This is how my processed data looks like

Here we see that for each act, there is the same colour, to the exception of number 5

I define my template 'mytemplate' with 6 colors

THEME = {
    'bar_colors': [
        '#861388',
        '#d4a0a7',
        '#dbd053',
        '#1b998b',
        '#A0CED9',
        '#3e6680'
    ],
    'background_color': '#ebf2fa',
    'font_family': 'Montserrat',
    'font_color': '#898989',
    'label_font_size': 16,
    'label_background_color': '#ffffff'
}

pio.templates['mytemplate'] = go.layout.Template(
        data=dict(
            bar=[go.Bar(marker_color=THEME['bar_colors'])]
        ),
        layout=go.Layout(
            font=dict(
                family=THEME['font_family'],
                color=THEME['font_color']
            ),
            paper_bgcolor=THEME['background_color'],
            plot_bgcolor=THEME['background_color'],
            hoverlabel=dict(
                bgcolor=THEME['label_background_color'],
                font_size=THEME['label_font_size']
            )
        )
    )

I add the template to my figure here, mixing it with simple_white

fig.update_layout(
        template=pio.templates["simple_white+mytemplate"],
        dragmode=False,
        barmode='relative',
        title='Lines per act',
        xaxis = dict(
            tickmode = 'array',
            tickvals = [1,2,3,4,5],
            ticktext = ['Act '+str(i) for i in range(1,6)]
        )
)

And I draw the bars here, iterating for each player

playerList = data.Player.unique()
for player in playerList:
    fig.add_trace(go.Bar(
        name=player,
        x=data.loc[data.Player==player].Act,
        y=data.loc[data.Player==player][f'{lineMode}'],
        hovertemplate=get_hover_template(player, lineMode)
))

I think the problem relies in how I iterate to add the bar, but I can't find any help in the documentation. Thank you in advance


Solution

  • I had never looked into the details of the theme before. The color settings for each theme are stored in the colorway, so to set your own color theme, set it in the colorway in the layout.

    import plotly.io as pio
    import plotly.graph_objects as go
    
    fig = go.Figure()
    
    THEME = {
        'color_way': [
            '#861388',
            '#d4a0a7',
            '#dbd053',
            '#1b998b',
            '#A0CED9',
            '#3e6680'
        ],
        'background_color': '#ebf2fa',
        'font_family': 'Montserrat',
        'font_color': '#898989',
        'label_font_size': 16,
        'label_background_color': '#ffffff'
    }
    
    pio.templates['mytemplate'] = go.layout.Template(
            # data=dict(
            #     bar=[go.Bar(marker_color=THEME['color_way'])]
            # ),
            layout=go.Layout(
                font=dict(
                    family=THEME['font_family'],
                    color=THEME['font_color']
                ),
                paper_bgcolor=THEME['background_color'],
                plot_bgcolor=THEME['background_color'],
                hoverlabel=dict(
                    bgcolor=THEME['label_background_color'],
                    font_size=THEME['label_font_size']
                ),
                colorway=THEME['color_way'], # update
            )
        )
    
    fig.update_layout(
            template=pio.templates["simple_white+mytemplate"],
            dragmode=False,
            barmode='relative',
            title='Lines per act',
            xaxis = dict(
                tickmode = 'array',
                tickvals = [1,2,3,4,5],
                ticktext = ['Act '+str(i) for i in range(1,6)]
            )
    )
    
    lineMode = 'LineCount'
    playerList = data.Player.unique()
    for i,player in enumerate(playerList):
        fig.add_trace(go.Bar(
            name=player,
            x=data.loc[data.Player==player].Act,
            y=data.loc[data.Player==player][f'{lineMode}'],
            #hovertemplate=get_hover_template(player, lineMode)
        ))
        fig.update_layout(barmode='stack')
    
    fig.show()
    

    enter image description here