I am using FontAwesome in my chart, and each data point is a symbol in FontAwesome font, displaying like an icon. Therefore, in the legend, I would like to use text (symbols in FontAwesome) to describe the items.
The code I am using is like:
from matplotlib.patches import Patch
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
ax = plt.gca()
ax.axis([0, 3, 0, 3])
prop = fm.FontProperties(fname='FontAwesome.otf', size=18)
ax.text(x=0, y=0, s='\uf1c7', color='r', fontproperties=prop)
ax.text(x=2, y=0, s='\uf050', color='g', fontproperties=prop)
plt.legend(handles=[Patch(color='r', label='label1'), Patch(color='g', label='label2')])
And the plot is like:
So what I want to do is to replace the color bar in the legend to the same icons as it in the plot.
The handle I am using is a list of Patches. But I found that it's hard to add text into Patch. I found there's a great solution to add picture into legend here: Insert image in matplotlib legend
I have tried using TextArea replacing BboxImage in that answer, but it doesn't work, and TextArea doesn't support fontproperties like axis.text.
So is there a way I can use text instead of markers in the legend?
For a solution using TextArea
see this answer. You would then need to recreate the fontproperties for the text inside the TextArea
.
Since here you want to show exactly the symbol you have as text also in the legend, a simpler way to create a legend handler for some text object would be the following, which maps the text to a TextHandler
. The TextHandler
subclasses matplotlib.legend_handler.HandlerBase
and its create_artists
produces a copy of the text to show in the legend. Some of the text properties then need to be adjusted for the legend.
import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerBase
import copy
ax = plt.gca()
ax.axis([-1, 3,-1, 2])
tx1 = ax.text(x=0, y=0, s=ur'$\u2660$', color='r',size=30, ha="right")
tx2 = ax.text(x=2, y=0, s=ur'$\u2665$', color='g',size=30)
class TextHandler(HandlerBase):
def create_artists(self, legend, orig_handle,xdescent, ydescent,
width, height, fontsize,trans):
h = copy.copy(orig_handle)
h.set_position((width/2.,height/2.))
h.set_transform(trans)
h.set_ha("center");h.set_va("center")
fp = orig_handle.get_font_properties().copy()
fp.set_size(fontsize)
# uncomment the following line,
# if legend symbol should have the same size as in the plot
h.set_font_properties(fp)
return [h]
labels = ["label 1", "label 2"]
handles = [tx1,tx2]
handlermap = {type(tx1) : TextHandler()}
ax.legend(handles, labels, handler_map=handlermap,)
plt.show()
Also see this more generic answer
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With