Search code examples
pythonmatplotlibchartsdata-visualization

Is there any matplotlib function to create a growth arrow between two points in a chart?


I was wondering if its possible to plot in a bar chart or in a line chart an arrow between two points of the charts. Something like the following picture:

enter image description here

I've been looking for something like this but haven't found anything similar neither here on stackoverflow nor on any other website.

Thanks a lot for your help!


Solution

  • There isn't any built-in matplotlib function to do this, but you can construct the annotations yourself using an arrow and a bbox. You can also wrap this code up in a function between any two data points to make this more generalizable.

    import matplotlib.pyplot as plt
    
    x=list('abcdefg')
    y=[10,20,30,40,50,123,240]
    
    fig, ax = plt.subplots(figsize=(12,8))
    ax.bar(x,y)
    
    ## add the text above the bars
    for idx, value in enumerate(x):
        ax.text(value, y[idx]+1, str(y[idx]))
    
    ## add the bar style connection patch, padding the y-coordinates
    t = ax.annotate("",
                xy=(x[0], y[0]+5), xycoords='data',
                xytext=(x[-1], y[-1]+5), textcoords='data',
                arrowprops=dict(arrowstyle="<-", color="0.5",
                                shrinkA=5, shrinkB=5,
                                patchA=None, patchB=None,
                                connectionstyle="bar,angle=-180,fraction=0.1",
                                ),
                )
    
    props = dict(boxstyle='round', facecolor="white")
    
    # place a text box in upper left in axes coords
    growth = "600%"
    ax.text("d", 240*1.18, growth, bbox=props)
    
    ## pretty up the chart by removing axes
    ax.spines['left'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.spines['top'].set_visible(False)
    ax.get_yaxis().set_visible(False)
    
    plt.show()
    

    enter image description here