Using ColorEmoji in Matplotlib
In previous post, we introduced mpl-simple-svg-parser package that lets you render svg. You can further use this to render color emoji.
You will need a color emoji font with COLR table. For example, Noto Color Emoji can be downaloaded from https://fonts.google.com/noto/specimen/Noto+Color+Emoji
You can transform the glyphs in the font to SVG, and uses mpl-simple-svg-parser, for example, to render it with matplotlib.
mpl-colr2svg is a package that does this. To convert emoji to svg, it uses nanoemoji . Altenatively, it can use blackrenderer to render emoji font to svg.
Code
import matplotlib.pyplot as plt
import pandas as pd
emoji_popularity = [["π" , 223.94 ],
["π€£" , 170.29 ],
["β€οΈ" , 95.02 ],
["π" , 116.92 ],
["π" , 95.02 ],
["π" , 77.3 ],
["β¨" , 76.34 ],
["π₯" , 71.52 ],
["π" , 70.15 ],
["π₯°" , 67.35 ],
]
df = pd.DataFrame(emoji_popularity, columns= ["Emoji" , "Popularity" ])
import seaborn as sns
sns.set_color_codes("muted" )
sns.set (font_scale = 1.5 )
fig, ax = plt.subplots(1 , 1 , figsize= (7 , 4 ), clear= True , num= 2 , layout= "constrained" )
sns.barplot(x= "Emoji" , y= "Popularity" , data= df,
label= "Emoji Popularity" , color= "b" )
from mpl_colr2svg import ColorEmoji
ftname = "NotoColorEmoji-Regular.ttf"
fontsize = 25
emoji = ColorEmoji(ftname)
for l in ax.get_xticklabels():
c = l.get_text()
xy = l.get_position()
l.set_visible(False )
emoji.annotate(ax, c, xy, xycoords= ("data" , "axes fraction" ),
box_alignment= (0.5 , 1 ), fontsize= fontsize,
annotation_clip= True )
ax.xaxis.labelpad = fontsize * 1.7
plt.show()
Letβs start with a simple example.
import matplotlib.pyplot as plt
from mpl_colr2svg import ColorEmoji
ftname = "NotoColorEmoji-Regular.ttf"
emoji = ColorEmoji(ftname)
c = "π€©"
fig, axs = plt.subplots(1 , 2 , figsize= (10 , 5 ), clear= True , num= 1 )
ax1 = axs[0 ]
ax1.set_title("draw in data coordinate" )
emoji.draw(ax1, c, size= 128 )
ax2 = axs[1 ]
emoji.annotate(ax2, c, (0.5 , 0.5 ), fontsize= 128 )
ax2.set_title("drawing_area with annotate" )
plt.show()
You may use blackrender. The default ColorEmoji
only support a sing glyph, but the blackrenderer version supports string of multiple charaters.
import matplotlib.pyplot as plt
from mpl_colr2svg.color_emoji_blackrenderer import ColorEmojiBlackrenderer
ftname = "seguiemj.ttf"
emoji = ColorEmojiBlackrenderer(ftname)
textString = "Lβ€οΈVE"
fig, ax = plt.subplots(1 , 1 , clear= True , num= 1 )
emoji.annotate(ax, textString, (0.5 , 0.5 ), fontsize= 128 )
plt.show()
Here is a more useful example. We start with a seabron plot of emoji popularity.
import matplotlib.pyplot as plt
import pandas as pd
emoji_popularity = [["π" , 223.94 ],
["π€£" , 170.29 ],
["β€οΈ" , 95.02 ],
["π" , 116.92 ],
["π" , 95.02 ],
["π" , 77.3 ],
["β¨" , 76.34 ],
["π₯" , 71.52 ],
["π" , 70.15 ],
["π₯°" , 67.35 ],
]
df = pd.DataFrame(emoji_popularity, columns= ["Emoji" , "Popularity" ])
import seaborn as sns
sns.set_color_codes("muted" )
sns.set (font_scale = 1.5 )
fig, ax = plt.subplots(1 , 1 , figsize= (7 , 4 ), clear= True , num= 2 , layout= "constrained" )
sns.barplot(x= "Emoji" , y= "Popularity" , data= df,
label= "Emoji Popularity" , color= "b" )
<Axes: xlabel='Emoji', ylabel='Popularity'>
/home/jjlee/miniconda3/envs/mpl-dev/lib/python3.10/site-packages/IPython/core/events.py:82: UserWarning: Glyph 129315 (\N{ROLLING ON THE FLOOR LAUGHING}) missing from font(s) DejaVu Sans.
func(*args, **kwargs)
/home/jjlee/miniconda3/envs/mpl-dev/lib/python3.10/site-packages/IPython/core/events.py:82: UserWarning: Glyph 128591 (\N{PERSON WITH FOLDED HANDS}) missing from font(s) DejaVu Sans.
func(*args, **kwargs)
/home/jjlee/miniconda3/envs/mpl-dev/lib/python3.10/site-packages/IPython/core/events.py:82: UserWarning: Glyph 10024 (\N{SPARKLES}) missing from font(s) DejaVu Sans.
func(*args, **kwargs)
/home/jjlee/miniconda3/envs/mpl-dev/lib/python3.10/site-packages/IPython/core/events.py:82: UserWarning: Glyph 128293 (\N{FIRE}) missing from font(s) DejaVu Sans.
func(*args, **kwargs)
/home/jjlee/miniconda3/envs/mpl-dev/lib/python3.10/site-packages/IPython/core/events.py:82: UserWarning: Glyph 129392 (\N{SMILING FACE WITH SMILING EYES AND THREE HEARTS}) missing from font(s) DejaVu Sans.
func(*args, **kwargs)
/home/jjlee/miniconda3/envs/mpl-dev/lib/python3.10/site-packages/IPython/core/pylabtools.py:152: UserWarning: Glyph 129315 (\N{ROLLING ON THE FLOOR LAUGHING}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/jjlee/miniconda3/envs/mpl-dev/lib/python3.10/site-packages/IPython/core/pylabtools.py:152: UserWarning: Glyph 128591 (\N{PERSON WITH FOLDED HANDS}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/jjlee/miniconda3/envs/mpl-dev/lib/python3.10/site-packages/IPython/core/pylabtools.py:152: UserWarning: Glyph 10024 (\N{SPARKLES}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/jjlee/miniconda3/envs/mpl-dev/lib/python3.10/site-packages/IPython/core/pylabtools.py:152: UserWarning: Glyph 128293 (\N{FIRE}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/jjlee/miniconda3/envs/mpl-dev/lib/python3.10/site-packages/IPython/core/pylabtools.py:152: UserWarning: Glyph 129392 (\N{SMILING FACE WITH SMILING EYES AND THREE HEARTS}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
Donβt worry if you see tofus. We will replace the x-tick labels with color emoji.
from mpl_colr2svg import ColorEmoji
ftname = "NotoColorEmoji-Regular.ttf"
fontsize = 25
emoji = ColorEmoji(ftname)
for l in ax.get_xticklabels():
c = l.get_text()
xy = l.get_position()
l.set_visible(False )
emoji.annotate(ax, c, xy, xycoords= ("data" , "axes fraction" ),
box_alignment= (0.5 , 1 ), fontsize= fontsize,
annotation_clip= True )
ax.xaxis.labelpad = fontsize * 1.7