Skip to content
Advertisement

Adding custom arrows with labels in seaborn relplot or a facetgrid

I am trying to add two custom arrows with labels in a seaborn relplot graph. I tried using the matplot arrow function which is not working because the seaborne relplot is a “facetgrid”. I did not see a specific arrow pointer function in seaborn docu. I want to draw an arrow at a specific x value between the y values of two benchmarks (b1 b2 in example)

Is there an easy way to do this? I added a simple code example, data and 2 images of what i try to achieve.

CODE:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import gc
import sys

if __name__ == '__main__':
        pfad = sys.argv[1]
        label = 'test'
        df1 = pd.read_csv(pfad, sep=';')

        sns_plot = sns.relplot(x="selectivity", ci=None, y="throughput", hue='benchmark', kind="line", data=df1,
                           dashes=False, markers=True, style="benchmark")

        sns_plot.savefig(label + ".png")
        plt.savefig(label + ".pdf", bbox_inches='tight')

        plt.show()

DATASET (example.csv in same folder)

benchmark;selectivity;throughput
b1;0.01;1426.89
b2;0.01;531.434
b1;0.03;826.89
b2;0.03;531.434
b1;0.05;626.89
b2;0.05;520.434

Currently my Graph looks like this:

Text

This is what I want to achieve:

Text

Advertisement

Answer

As mentioned in the comments, I flattened the axes, got the values from the line chart, and added text annotations and arrows respectively.

if __name__ == '__main__':
    pfad = sys.argv[1]
    label = 'test'
    df1 = pd.read_csv(pfad, sep=';')

    sns_plot = sns.relplot(x="selectivity", ci=None, y="throughput", hue='benchmark', kind="line", data=df1,
                       dashes=False, markers=True, style="benchmark")
    xydata = []
    for ax in sns_plot.axes.flat:
        for li in ax.lines:
            xydata.append(li.get_xydata())
            
    ax.text(xydata[0][0][0]+0.001, (xydata[0][0][1]+xydata[1][0][1])/2, '2.5X speedup')
    ax.text(xydata[1][2][0]+0.001, (xydata[0][2][1]+xydata[1][2][1])/2, '1.3X speedup')
    ax.annotate('',
                xy=(xydata[0][0][0], xydata[0][0][1]),
                xytext=(xydata[0][0][0], xydata[1][0][1]),
                xycoords='data',
                arrowprops=dict(facecolor='black',width=2.0,headwidth=7.0,headlength=7.0,shrink=0.01))
    ax.annotate('',
                xy=(xydata[1][2][0], xydata[0][2][1]),
                xytext=(xydata[1][2][0], xydata[1][2][1]),
                xycoords='data',
                arrowprops=dict(facecolor='black',width=2.0,headwidth=7.0,headlength=7.0,shrink=0.01))
    
    #sns_plot.savefig(label + ".png")
    #plt.savefig(label + ".pdf", bbox_inches='tight')

    plt.show()

enter image description here

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement