1

I'm moving a Pandas legend but trying to keep it as patches. It swaps to lines when I try to adjust the parameters - is there a setting I'm missing to stop this happening or am I resetting the legend or something by accident? What am I doing wrong?

The code is a bit complicated so I'm putting in the useful bits. Don't worry about bad formatting, I just skipped out a load of formatting lines to make it simpler to understand.

Simplified code:

my_colors = list(['goldenrod', 'royalblue', 'darkviolet', 'firebrick'])

#set up subplots
fig_heatprop, axes_heatprop = plt.subplots(nrows=2, ncols=1, sharex=True, gridspec_kw = {'height_ratios':[8, 1]})

#make totales percentages
df_touse_perc = df_touse.divide(df_touse.sum(axis=1), axis=0).multiply(100)

ax = df_touse_perc.plot(kind='area', stacked=True, color=my_colors, ax=axes_heatprop[0]) #.legend(bbox_to_anchor=(0.2, -0.3), ncol=2)

does this: enter image description here

but if I try to move the legend, it swaps it from patches to lines

#move legend
ax.legend(loc=9, bbox_to_anchor=(0.2, -0.2), ncol=2)

enter image description here

mjp
  • 1,618
  • 2
  • 22
  • 37
  • Possible duplicate of [Move existing legend in Matplotlib 1.5.1](http://stackoverflow.com/questions/35562515/move-existing-legend-in-matplotlib-1-5-1) – Stop harming Monica Jan 17 '17 at 14:23
  • Doesn't look like a duplicate to me. I am trying to retain the patches style of legend after moving it. I can create and move it fine – mjp Jan 17 '17 at 14:43
  • That's exactly what the accepted answer to that question does: it keeps the labels and handles (in your case patches) of the original legend without you having to manually recreate them. – Stop harming Monica Jan 17 '17 at 17:01
  • Thanks @Goyo , sorry I didn't read it correctly apparently. I will try that way too. – mjp Jan 19 '17 at 15:18

1 Answers1

1

First remove the default legend by setting the attribute legend to False in the last line of your main code block

ax = df_touse_perc.plot(kind='area', 
                        stacked=True, 
                        color=my_colors, 
                        ax=axes_heatprop[0],
                        legend=False) 

For the patches you could create a patch per colour and have a list of them and finally you can set the legend using the line you mentioned alongside setting the handles attribute to the list of patches created

import matplotlib.patches as mpatches
patch =[]
for c,l in zip(my_colors,df_touse_perc.columns.tolist()):
     patch.append(mpatches.Patch(color=c, label=l))

ax.legend(handles=patch,loc=9, bbox_to_anchor=(0.2, -0.2), ncol=2)
sgDysregulation
  • 4,309
  • 2
  • 23
  • 31
  • 1
    The OP wants the patches. – Stop harming Monica Jan 17 '17 at 14:24
  • OK, I've added a roughly thought suggestion, Thanks! – sgDysregulation Jan 17 '17 at 14:44
  • 1
    I was hoping there was some setting to change to stop it resetting it to lines instead of patches but this is a good enough work around. Thanks! Additions: You dropped a closing bracket on the `patch.append` line and I used `list(df_touse_perc)` instead of `my_lables` to get an automatic list of the labels from the dataframe column headings – mjp Jan 17 '17 at 14:51