Search code examples
pythonmatplotliblegendaxestwinx

Combining labels for a legend from two separate axes objects error


I have a graph which needs two y-axis. Having created the second y-axis I now want to add the labels from each of the two axes instances into one legend, I have seen a method on SO here Secondary axis with twinx(): how to add to legend? but it doesn't produce the legend, instead I get a traceback error.

Some of the code

plot4 = my_figure_trap.add_subplot(111) # adding the subplot
print('\n'*2, 'DEBUG+++++++++type of plot4: ',type(plot4),'\n'*2)

lns1 = plot4.scatter(x=df["Frequency_khz"], y= df["Velocity_ms"], marker='.', c='none', edgecolor='b', label = 'Velocity m/s')
lns2 = plot4.scatter(x=df["Frequency_khz"], y= df["Volume_pl"], marker='.', c='none', edgecolor='r', label = 'Volume_pl')
plot4.set_xlabel('Frequency $(kHz)$', color = 'midnightblue')

plot4.set_ylabel('Velocity $(m/s)$ and Drop Volume $(pL)$', color = 'midnightblue')
plot4.set_xticks(np.arange(freq_axis_origin, freq_axis_max, 10))
plot4.set_yticks(np.arange(vel_axis_origin, vel_axis_max, 1))
plot4.set_facecolor('xkcd:light gray')



plot4a = plot4.twinx()

# LOGIC FOR TRAJECTORY PLOT
# get current traj method
if get_traj_method()==0:
    lns3 = plot4a.scatter(x=df["Frequency_khz"], y= df["Traj_deviation_mrads"], marker='.', c='none', edgecolor='g', label = 'Traj Deviation mrads')
    plot4a.set_ylim([0-user_traj_range, user_traj_range])
    plot4a.set_ylabel('Trajectory deviation from 90$^\circ$ $(mRads)$', color = 'midnightblue')


else:
    #get_traj_method()==1:
    lns3 = plot4a.scatter(x=df["Frequency_khz"], y= df["Trajectory_deg"], marker='.', c='none', edgecolor='g', label = 'Trajectory ($^\circ$)')
    plot4a.set_ylim([90-user_traj_range, 90+user_traj_range])
    plot4a.set_ylabel('Trajectory($^\circ$)', color = 'midnightblue')




lns = lns1+lns2+lns3
print(lns)
labs = [l.get_label() for l in lns]
print(labs)
plot4.legend(lns, labs, loc="upper right")

The traceback error is :

Exception in Tkinter callback
Traceback (most recent call last):
  File "/Users/.../opt/anaconda3/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
    return self.func(*args)
  File "/Users/.../Desktop/tk_gui_grid/e_07.py", line 204, in plot_frequency_sweep
    lns = lns1+lns2+lns3
TypeError: unsupported operand type(s) for +: 'PathCollection' and 'PathCollection'
(base) ... tk_gui_grid % 

Solution

  • I think there are a couple of ways to do this but the option I personally prefer is the following:

    ### Do everything for plot4 as before
    ...
    handles4,labels4 = plot4.get_legend_handles_labels()
    
    ### Do everything for plot4a
    ...
    handles4a,labels4a = plot4a.get_legend_handles_labels()
    
    ### Combine the legend handles and labels to make a new legend object
    handles = handles4 + handles4a
    labels = labels4 + labels4a
    plot4.legend(handles, labels)
    
    

    It'll look something like this:

    enter image description here