How I got Matplotlib to plot Apple Color Emojis | by Brienna Herold | Towards Data Science

If you try to plot emojis, you might see something like this:
Although we explicitly specified it as the font, these emojis are not Apple Color Emoji. They are from the font DejaVu Sans, the default font that took over after Matplotlib failed to process our specified font, throwing the following error:
RuntimeError: In FT2Font: Could not set the fontsize.
A few of many related questions on Stack Overflow about plotting emojis in Matplotlib:
How to plot (high quality) emoji in matplotlib?
matplotlib: annotate plot with Emoji labels
Emoji in Matplotlib figures on OS X
Emojis in matplotlibs xticks
Could not load the emoji font in Matplotlib
All remain unanswered. It simply cannot be done with recent versions of Matplotlib. A look at Matplotlib’s GitHub repo reveals Issues #3135, #4492, and #12830, the first of which has been open for almost eight years as of 2022.
Why can’t Matplotlib plot emojis from the Apple Color Emoji font? How can we overcome this lack of functionality to get the emojis plotted? This post answers these questions.
Apple Color Emoji is a TrueType Collection (TTC) file. This format combines multiple fonts into a single file, to save space. FT2Font, the dependency which threw that runtime error we saw earlier, only supports getting the first font from a TTC file. While this might work, limitations of the conversion dependency, ttconv, prevent the backends from actually using this font.
There’s a solution coming in the form of pull request #9787. It currently awaits further review.
While we wait for the pull request to be merged, there exists an immediate solution in which we can successfully plot emojis using Matplotlib.
Enter Mplcairo. A “new, essentially complete implementation of a cairo backend for Matplotlib,” Mplcairo improves on several points in the original backend. Most notably, Mplcairo introduces support for using the first font in a TTC file.
It seems like we should be able to easily install Mplcairo via pip install mplcairo, but for me this installation continued to throw errors when I tried to import it into my code.
Instead, I git cloned the repo onto my machine (git clone https://github.com/matplotlib/mplcairo.git), and then followed the build and installation instructions. I summarize my process below.
Since wheels are not available for OS X, we need to build the OS X wheel ourselves using Terminal. To do this, we need the following dependencies:
C++ compiler with C++17 support, e.g. GCC ≥ 7.2 or Clang ≥ 5.0. I installed the latter using brew install llvm.
Cairo and FreeType headers, and pkg-config information to locate them. Since cairo introduced color support for emojis in version 1.15.8, we need a cairo version no earlier than that. Until conda-forge updates its cairo, brew install cairo. Then pip install pycairo.
Once we have acquired the dependencies, we can activate llvm (as documented by brew info llvm) and build the OS X wheels, while in the root folder of mplcairo:
echo 'export PATH="/usr/local/opt/llvm/bin:$PATH"' >> ~/.bash_profile                source ~/.bash_profileexport LDFLAGS="-L/usr/local/opt/llvm/lib"export CPPFLAGS="-I/usr/local/opt/llvm/include"export CC='/usr/local/opt/llvm/bin/clang'export CXX='/usr/local/opt/llvm/bin/clang++'tools/build-macos-wheel.sh
Now that we’ve built Mplcairo, we can install it systemwide (or in our virtual environment) with pip install dist/mplcairo-0.1.post47+g109b19f-cp37-cp37m-macosx_10_9_x86_64.whl.
This might be an anomaly, but while building in Terminal, my Python downgraded from version 3.7.0 to 3.6.5. When I opened a new Terminal window, Python was at 3.7.0 again and I was able to install the wheel.
Note (August 16, 2020): Confirm that tools/build-macos-wheel.sh and dist/mplcairo-0.1.post47+g109b19f-cp37-cp37m-macosx_10_9_x86_64.whl are the correct filepaths — when I first published this article in 2018, they were named differently.
To plot our emojis, we simply import Mplcairo and set it as the new backend of Matplotlib.
import matplotlib, mplcairoprint('Default backend: ' + matplotlib.get_backend()) matplotlib.use("module://mplcairo.macosx")print('Backend is now ' + matplotlib.get_backend())
After running the script above, you should see this output:
Default backend: module://ipykernel.pylab.backend_inlineBackend is now module://mplcairo.macosx
Your default backend may differ depending on where you are running your script. My default backend is from Jupyter Notebook. (If you are using Jupyter Notebook, you must reset the kernel before you can reset the backend. You also must reset the backend before importing matplotlib.pyplot.)
Once you get Mplcairo up and running, Matplotlib plots emojis beautifully.
Complete code:
If you’d like to read more of my articles or explore millions of other articles, you can sign up for Medium membership:
brienna.medium.com
You can also subscribe to my email list to get notified whenever I publish a new article:
brienna.medium.com
Some other stories from me that might interest you: