Search code examples
pythonplotlybar-chartstacked-bar-chartgrouped-bar-chart

stacked and grouped barchart


I have this data set

import pandas as pd
import plotly.express as px

elements = pd.DataFrame(data={"Area": ["A", "A", "A", "B", "B", "C", "C", "C"], "Branch": ["a1", "f55", "j23", "j99", "ci2", "p21", "o2", "q35"], "Good": [68, 3, 31, 59, 99, 86, 47, 47], "Neutral": [48, 66, 84, 4, 83, 76, 6, 89],"Bad": [72, 66, 50, 83, 29, 54, 84, 55]})

  Area Branch  Good  Neutral  Bad
0    A     a1    68       48   72
1    A    f55     3       66   66
2    A    j23    31       84   50
3    B    j99    59        4   83
4    B    ci2    99       83   29
5    C    p21    86       76   54
6    C     o2    47        6   84
7    C    q35    47       89   55

and i'm trying to plot it and get something that looks like this enter image description here

stacked and grouped with labels, so I tried this

fig_elements = px.bar(elements, x='Branch', y=["Good", "Neutral", "Bad"], orientation="v", template="plotly_dark", facet_col='Area')
fig_elements.update_layout(plot_bgcolor="rgba(0,0,0,0)", xaxis=(dict(showgrid=False)), yaxis=(dict(showgrid=False)), barmode="stack")

enter image description here

can't add labels and on the bars, and areas have all branches not only the branches that belong to it, how can I fix that and add the labels?


Solution

  • import plotly.graph_objects as go
    df = elements.melt(id_vars=['Area', 'Branch'], value_vars=['Good', 'Neutral', 'Bad'], var_name='Rating')
    df
    ###
       Area Branch   Rating  value
    0     A     a1     Good     68
    1     A    f55     Good      3
    2     A    j23     Good     31
    3     B    j99     Good     59
    4     B    ci2     Good     99
    5     C    p21     Good     86
    6     C     o2     Good     47
    7     C    q35     Good     47
    8     A     a1  Neutral     48
    9     A    f55  Neutral     66
    10    A    j23  Neutral     84
    11    B    j99  Neutral      4
    12    B    ci2  Neutral     83
    



    Plot

    rating_color = ['#17BEBB', '#FFD97D', '#EE6055']
    fig = go.Figure()
    fig.update_layout(barmode='stack', width=900, height=800, uniformtext_minsize=8, uniformtext_mode='hide')
    for r, c in zip(df['Rating'].unique(), rating_color):
        df_plot = df[df['Rating'] == r]
        fig.add_trace(
            go.Bar(
                x=[df_plot['Area'], df_plot['Branch']],
                y=df_plot['value'],
                marker_color=c,
                name=r,
                text=df_plot['value'],
                width=0.45,
                textposition='auto')
        )
    
    fig.show()
    

    enter image description here