Search code examples
plotlystylesbar-chartborderplotly-python

Plotly bar chart with dotted or dashed border - How to implement?


I’m trying to create a bar chart like the image below: The chart I want to reproduce

And I'm almost there, but I'm not finding any reference about setting a border style dashed or dotted;

Below is a picture of the chart created by me:

The chart I did so far



I will add a minimal reproducible code below:

import plotly.graph_objects as go

data={"years":[2019,2020,2021,2022],
      "total_value":[100000000000,220000000000,350000000000,410000000000]}

def bar_styled(data):
    
    blank = 'rgba(0,0,0,0)'
    colors =["#FED241", "#FED241", "#143DCB", blank]

    fig = go.Figure(data=[go.Bar(
        x=data['years'],
        y=data['total_value'],
        marker_color=colors, # marker color can be a single color value or an iterable
        marker_line_width=3
    )])

    fig.update_layout(title_text=None, paper_bgcolor=blank, 
                      height=300, margin={"b":4, "t":4, "l":8, "r":8 })
    
    color_list=fig.data[0]["marker"]["color"]
    
    fig.data[0]["marker"]['line']["color"]=['#FED241' if val == blank else  blank for val in color_list]

    fig.update_xaxes(type='category')
    
    return fig

bar_styled(data)

Any references or help about how I could implement this is very appreciated;

Thank you in advance guys, Regards, Leonardo


Solution

  • According to this Plotly forum post, setting the line style is not possible for bar charts - I looked at the object fig.data[0]["marker"]['line'] which is of type plotly.graph_objs.bar.Marker and there are no properties that would allow you to set the style of the line.

    However, you can plot the blank bar so that the xaxis tick shows up, and then use Plotly shapes to draw a rectangle with the desired style around it.

    When you use fig.add_shape to draw a rectangle in plotly on a bar chart, the x-coordinate of the center of the first bar will be 0.0, the center of second bar will be 1.0, and so on... this means the middle of the bar corresponding to 2022 will be located at x-coordinate 3.0.

    And since the default width of the bar is 0.8, this means you will want to pass x0 = 2.6, x1 = 3.4 to fig.add_shape when you draw the rectangle. You can also specify the line style of the rectangle as dash.

    import plotly.graph_objects as go
    
    data={"years":[2019,2020,2021,2022],
          "total_value":[100000000000,220000000000,350000000000,410000000000]}
    
    ## this only works if the year occurs once in the data
    def get_plotly_xcoordinates(year, width=0.8):
        x_location = data["years"].index(year)
        print(x_location)
        return x_location - width/2, x_location + width/2
    
    def bar_styled(data):
        
        blank = 'rgba(0,0,0,0)'
        colors =["#FED241", "#FED241", "#143DCB", blank]
    
        fig = go.Figure(data=[go.Bar(
            x=data['years'],
            y=data['total_value'],
            marker_color=colors, # marker color can be a single color value or an iterable
            marker_line_width=3
        )])
    
        fig.update_layout(title_text=None, paper_bgcolor=blank, 
                          height=300, margin={"b":4, "t":4, "l":8, "r":8 })
        
        # color_list=fig.data[0]["marker"]["color"]
        
        # fig.data[0]["marker"]['line']["color"]=['#FED241' if val == blank else blank for val in color_list]
        x0,x1 = get_plotly_xcoordinates(2022)
    
        fig.add_shape(type="rect", xref="x", yref="y",
            x0=x0, y0=0,
            x1=x1, y1=410000000000,
            line=dict(color="#FED241",dash="dash",width=3)
        )
    
        fig.update_xaxes(type='category')
        
        return fig
    
    fig = bar_styled(data)
    

    enter image description here