matchifang
matchifang

Reputation: 5450

How to create a legend of both color and marker?

I want to show both color and marker in the legend. Colors mean one thing and markers mean another. It should look something like the attached image. This is the current code I have:

x = np.arange(20)
y = np.sin(x)

fig, ax = plt.subplots()
line1 = ax.scatter(x[:10],y[:10],20, c="red", picker=True, marker='*')
line2 = ax.scatter(x[10:20],y[10:20],20, c="red", picker=True, marker='^')

ia = lambda i: plt.annotate("Annotate {}".format(i), (x[i],y[i]), visible=False)
img_annotations = [ia(i) for i in range(len(x))] 

def show_ROI(event):
    for annot, line in zip([img_annotations[:10],img_annotations[10:20]], [line1, line2]):
        if line.contains(event)[0]:
            ...
    fig.canvas.draw_idle()

fig.canvas.mpl_connect('button_press_event', show_ROI)

plt.show()

enter image description here

Upvotes: 10

Views: 7032

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339705

The following would be a generic example of how to use proxy artists to create a legend with different markers and colors.

import matplotlib.pyplot as plt
import numpy as np

data = np.random.rand(8,10)
data[:,0] = np.arange(len(data))

markers=["*","^","o"]
colors = ["crimson", "purple", "gold"]


for i in range(data.shape[1]-1):
    plt.plot(data[:,0], data[:,i+1], marker=markers[i%3], color=colors[i//3], ls="none")

f = lambda m,c: plt.plot([],[],marker=m, color=c, ls="none")[0]

handles = [f("s", colors[i]) for i in range(3)]
handles += [f(markers[i], "k") for i in range(3)]

labels = colors + ["star", "triangle", "circle"]

plt.legend(handles, labels, loc=3, framealpha=1)

plt.show()

enter image description here

Upvotes: 20

Related Questions