1

I'm using seaborn to plot the results of some work using Benford's Law. The plot has two axes: a barplot representing the relative frequency of the digits in the input data, and a linechart representing the expected frequencies from Benford's Law.

As in this question, I used the style=True option so that I could control the style of my line. Unfortunately, this causes a duplicate entry in my legend, which I can't seem to remove. How can I correct the duplicate entry in my legend?

Current code:

def plot(inputdata, digits, y_col_actual, y_col_expected):

    plt.rcParams['patch.force_edgecolor']=True

    ax1 = sns.barplot(
        data=inputdata,
        x = digits,
        y = y_col_actual,
        color = '#B2E8C2',
        label='Actual Data'
        )
    ax1.set(ylabel='Relative Frequency')

    ax2 = sns.lineplot(
        data=inputdata,
        x = digits,
        y = y_col_expected,
        ax = ax1,
        zorder = 5,
        color = 'black',
        style=True,
        dashes=[(2,2)],
        markers=True,
        label='Benfords Law',
        )
    
    plt.show()

And the resulting plot:

enter image description here

indigochild
  • 350
  • 1
  • 5
  • 21
  • 1
    What did you try to do with style? Style should be the name of a column in the DataFrame, is not a Boolean option. That's why it appears in the legend. Probably what you want to set is `dashes=True` or `linestyle='--'` – jjsantoso Jan 24 '21 at 02:39
  • @jjsantoso style needs to be set in order to use dashes. There is only one line (no categories to distinguish), so I don't want to provide a column name - so True is a valid alternative. Setting dashes to True doesn't actually result in any dashed lines. – indigochild Jan 24 '21 at 02:59

2 Answers2

1

Not a very nice solution but this works for me when I append it to the end of your plot function:

handles, labels = ax2.get_legend_handles_labels()
labels[1] = "_True"
ax2.legend(handles, labels)

This works because matplotlib ignores any labels beginning with an underscore. Since in your case, labels[1] = "True" is the offender, it has been overwritten as "_True".

Kris
  • 564
  • 2
  • 6
1

Put legend=False in lineplot, then add the legend yourself:

ax = sns.lineplot(
    x=[1, 2, 3], y=[1, 2, 3],
    style=True, dashes=[(2, 2)],
    label="Test", legend=False
)
ax.legend()
mwaskom
  • 46,693
  • 16
  • 125
  • 127