Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
663 views
in Technique[技术] by (71.8m points)

python - How to add a string as the artist in matplotlib legend?

I am trying to create a legend in a python figure where the artist is a string (a single letter) which is then labelled. For example I would like a legend for the following figure:

import numpy as np
import matplotlib.pyplot as plt
import string

N = 7
x = np.random.rand(N)
y = np.random.rand(N)
colors = np.random.rand(N)
area = np.pi * (15 * np.random.rand(N))**2 

plt.scatter(x, y, s=area, c=colors, alpha=0.5)
for i,j in enumerate(zip(x,y)):
    plt.annotate(list(string.ascii_uppercase)[i],xy=j)
plt.show()

Where the legend is something like:

A - Model Name A

B - Model Name B

C - Model Name C

D - Model Name D

etc.etc.

What I can't work out how to do is place 'A', 'B', .... as the artist for the legend text. I can see how you would use a line or Patch, or something similar. But in general is there a way to use a string as the artist instead of, say, a line?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't think there's a legend handler for text (see the list of available ones here). But you can implement your own custom legend handler. Here I'll just modify the example at the above link:

import matplotlib.pyplot as plt
import matplotlib.text as mpl_text

class AnyObject(object):
    def __init__(self, text, color):
        self.my_text = text
        self.my_color = color

class AnyObjectHandler(object):
    def legend_artist(self, legend, orig_handle, fontsize, handlebox):
        print orig_handle
        x0, y0 = handlebox.xdescent, handlebox.ydescent
        width, height = handlebox.width, handlebox.height
        patch = mpl_text.Text(x=0, y=0, text=orig_handle.my_text, color=orig_handle.my_color, verticalalignment=u'baseline', 
                                horizontalalignment=u'left', multialignment=None, 
                                fontproperties=None, rotation=45, linespacing=None, 
                                rotation_mode=None)
        handlebox.add_artist(patch)
        return patch

obj_0 = AnyObject("A", "purple")
obj_1 = AnyObject("B", "green")

plt.legend([obj_0, obj_1], ['Model Name A', 'Model Name B'],
           handler_map={obj_0:AnyObjectHandler(), obj_1:AnyObjectHandler()})

plt.show()

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...