11

Here is a simplified plot of the situation:

plot example

Instead of have each data point marker have a separate label, I want to be able to have one label for a set of different markers. I would like to be able to have a legend like:

<triangle> <square> <hexagon> <diamond> <circle> Shotcrete strength data points
<green line> 10 minute strength
<blue line> 60 minute strength
<yellow line> 1 day strength
<orange line> 7 day strength
<red line> 28 day strength

I want to do this because in the final plot I will have three sets of data points and showing 18 (3 sets * 6 points/set) marker/label combinations will be messy.

I am using Matplotlib with Python 2.7.

DSM
  • 342,061
  • 65
  • 592
  • 494
CrazyArm
  • 356
  • 1
  • 3
  • 13
  • For people facing a similar issue using Python and matplotlib v 3.0 and above, the answer I have posted to [this question](https://stackoverflow.com/questions/35527093/how-to-add-bar-and-line-under-the-same-label-in-a-legend/) may help. – Patrick FitzGerald Dec 22 '20 at 08:26

1 Answers1

3

Note: This answer is kept up as a guide to the correct answer - but it does not solve the stated problem. Please see the edit below for the problem of Patch collections not being support in matplotlib.


One way to go about this, if you want complete customization is to use a so-called Proxy Artist:

from pylab import *

p1 = Rectangle((0, 0), 1, 1, fc="r")
p2 = Circle((0, 0), fc="b")
p3 = plot([10,20],'g--')
legend([p1,p2,p3], ["Red Rectangle","Blue Circle","Green-dash"])

show()

Here you can specify exactly what you'd like the legend to look like, and even use non-standard plot shapes (patches).

Edit: There is some difficulty with this method, matplotlib only supports these Artists in a legend without tweaking. For matplotlib v1.0 and earlier, the supported artists are as follows.

Line2D
Patch
LineCollection
RegularPolyCollection
CircleCollection

Your request of multiple scatter points would be done with a Patch Collection, which is not supported above. In theory with v1.1, this is possible but I do not see how.

Hooked
  • 84,485
  • 43
  • 192
  • 261
  • 2
    I am currently using psuedo lines to make my legend. I think I might be able to use something like this (http://matplotlib.sourceforge.net/users/legend_guide.html#legend-handler): `code` z = np.random.randn(10) p1a, = plt.plot(z, "ro", ms=10, mfc="r", mew=2, mec="r") # red filled circle p1b, = plt.plot(z[:5], "w+", ms=10, mec="w", mew=2) # white cross plt.legend([p1a, (p1a, p1b)], ["Attr A", "Attr A+B"]) `code` to combined multiple markers onto one line. – CrazyArm Feb 13 '12 at 15:03
  • @CrazyArm as far as I understand it, you'll have to define a custom shape for the ` ` which is why I gave the solution as I did. You may be able to extract the symbol shape from the scatter plot source (or from scatter itself) and use that with the custom shape as input to `legend`. – Hooked Feb 13 '12 at 15:08
  • Thanks. I think I understand how to make an individual custom marker in the legend (a rectangle, or circle like you mentioned), but I don't know how to go about combining two of them. This (http://matplotlib.sourceforge.net/examples/api/scatter_piecharts.html) does it by overlapping multiple symbols, but I don't know how they would show it on a legend. – CrazyArm Feb 13 '12 at 15:54
  • 1
    Also, your code results in two rectangles (one red, one blue) in the legend, not a rectangle a circle. – CrazyArm Feb 13 '12 at 16:10
  • @CrazyArm your solution helped me solve my problem: http://stackoverflow.com/questions/28732845/combine-two-pyplot-patches-for-legend/28735010#28735010. Thanks! – Blink Feb 26 '15 at 05:22