Search code examples
plotlybar-chart

Wants to create horizontal bar chart with customized text annotations with various positions


I want to create a horizontal bar chart as given below enter image description here

How can I achieve this,

I am working this with following code

x_data = [float(23.1), float(42.21)]
            y_data = ['Emission', 'Green Energy']
            fig = go.Figure()
            fig.add_trace(go.Bar(
                y=y_data,
                x=x_data,
                orientation='h',
                marker=dict(
                    color='rgba(246, 78, 139, 0.6)',
                    line=dict(color='rgba(246, 78, 139, 1.0)', width=0)
                ),
                width=.2
            ))
            fig.add_trace(go.Bar(
                y=y_data,
                x=[100-x_data[0], 100-x_data[1]],
                orientation='h',
                marker=dict(
                    color='rgba(58, 71, 80, 0.6)',
                    line=dict(color='rgba(58, 71, 80, 1.0)', width=0)
                ),
                width=.2
            ))
            fig.update_layout(paper_bgcolor="rgba(0,0,0,0)",
                          plot_bgcolor="rgba(0,0,0,0)", barmode='stack')
            annotations = []
            title = ['Emission', 'Green Energy Generated']
            for i in range(0, 2):
                annotations.append(
                    dict( x=x_data[i], y=y_data[i],
                                    text=title[i],
                                    font=dict(family='Arial', size=12,
                                              color='#27235c'),
                                    xshift=0,
                                    yshift=20,
                                    showarrow=True))
            # fig.update_traces(texttemplate='%{y}', textposition='auto')
            fig.update_yaxes(visible=False, showticklabels=False)
            fig.update_layout(xaxis_title=None)
            fig.update_layout(
                activeselection_fillcolor=settings['graph_design_theme'][0])
            fig.update_layout(autosize=False, width=310, height=310)
            fig.update_layout(margin=dict(t=50, b=50, l=50, r=50))
            fig.update_layout(annotations=annotations)
            fig.update_layout(showlegend=False)

I need to replicate as such in that image, suggest me to pick a graph and how can I achieve this?


Solution

  • There are many ways to create the desired graphs, but I have used subplots to place each graph, hide the x- and y-axes and annotate the text. I have not created all the annotations, but I have added code to allow you to extend yours. This type of graph inevitably requires manual configuration, so expressing your preferences involves a lot of trial and error.

    import plotly.graph_objects as go
    from plotly.subplots import make_subplots
    
    x_data = [float(23.1), float(42.21)]
    y_data = ['Emission', 'Green Energy']
    
    # fig = go.Figure()
    fig = make_subplots(rows=2, cols=1, subplot_titles=y_data, shared_xaxes=True, vertical_spacing=0.00)
    
    fig.add_trace(go.Bar(
        y=[y_data[0]],
        x=[x_data[0]],
        orientation='h',
        marker=dict(
            color='rgba(58, 71, 80, 0.6)',
            line=dict(color='rgba(246, 78, 139, 1.0)', width=0)
        ),
        width=.2,
        showlegend=False
    ), row=1, col=1)
    
    fig.add_trace(go.Bar(
        y=[y_data[0]],
        x=[100-x_data[0]],
        orientation='h',
        marker=dict(
            color='rgba(246, 78, 139, 0.6)',
            line=dict(color='rgba(246, 78, 139, 1.0)', width=0)
        ),
        width=.2,
        showlegend=False
    ), row=1, col=1)
    
    fig.add_trace(go.Bar(
        y=[y_data[1]],
        x=[x_data[1]],
        orientation='h',
        marker=dict(
            color='rgba(58, 71, 80, 0.6)',
            line=dict(color='rgba(246, 78, 139, 1.0)', width=0)
        ),
        width=.2,
        showlegend=False
    ), row=2, col=1)
    
    fig.add_trace(go.Bar(
        y=[y_data[1]],
        x=[100-x_data[1]],
        orientation='h',
        marker=dict(
            color='rgba(246, 78, 139, 0.6)',
            line=dict(color='rgba(58, 71, 80, 1.0)', width=0)
        ),
        width=.2,
        showlegend=False
    ), row=2, col=1)
    
    fig.add_annotation(x=2.0, y=0, yshift=-15, text=str(x_data[0]), showarrow=False, row=1, col=1)
    fig.add_annotation(x=99, y=0, yshift=-15, text=str(100), showarrow=False, row=1, col=1)
    fig.add_annotation(x=99, y=.4, yshift=-15, text='goal', showarrow=False, row=1, col=1)
    
    fig.add_annotation(x=2.0, y=0, yshift=-15, text=str(x_data[1]), showarrow=False, row=2, col=1)
    fig.add_annotation(x=99, y=0, yshift=-15, text=str(100), showarrow=False, row=2, col=1)
    
    fig.update_layout(title='CARBON FOOTPRINT', title_font=dict(family='Arial', size=18, color='white'))
    for i in range(0, 2):
        fig['layout']['annotations'][i]['x'] = 0.0
        fig['layout']['annotations'][i]['xanchor'] = 'left'
        if i == 0:
            fig['layout']['annotations'][i]['y'] = 0.9
        elif i ==1:
            fig['layout']['annotations'][i]['y'] = 0.4
            
    fig.update_layout(barmode='stack', template='plotly_dark')
    fig.update_layout(autosize=False, width=310, height=310, margin=dict(t=50, b=50, l=50, r=50))
    fig.update_xaxes(showticklabels=False, showgrid=False)
    fig.update_yaxes(showticklabels=False, showgrid=False)
    fig.update_xaxes(zeroline=True, zerolinewidth=1, zerolinecolor='black')
    
    fig.show()
    

    enter image description here