A (new) cairo backend for matplotlib

Hi all,

Following my frustration with the somewhat incomprehensible (... to me) Agg
backend codebase, and as recently mentioned on the gitter channel, I have
hacked together a mostly complete native cairo backend for matplotlib. See
https://github.com/anntzer/mpl_cairo (which also lists the missing features
that I can see). It is based on pybind11 and requires a C++ compiler with
C++17 support (e.g., GCC 7.1).

One of the original motivations was to get rid of the "inaccurate marker
stamping" issue (https://github.com/matplotlib/matplotlib/issues/7262,
https://github.com/matplotlib/matplotlib/issues/7233). Yes, I could have
tried to revert the original patch too... The repository contains a few
examples where the new cairo backend places markers much more accurately.

Removing that optimization means that the backend is a bit slower than Agg
for drawing markers (though not more than ~1.5x); for other tasks it
appears to be nearly as fast. It is dramatically faster than the current
(somewhat buggy) pycairo/cairocffi-based cairo backend (gtk3cairo, and
qt5cairo with https://github.com/matplotlib/matplotlib/pull/8771).

Being a native backend allows us to directly call libraries such as
freetype (bypassing -- in part -- the longstanding suggestion that ft2font
needs to be rewritten); it should likewise be possible to support complex
text layout (http://matplotlib.org/devel/MEP/MEP14.html) with the
appropriate library (from a quick search,
https://github.com/HOST-Oman/libraqm seems to be an interesting
possibility). Additionally, cairo itself has an OpenGL (cairo-gl) backend,
which we may look into (currently, the cairo calls go into an image buffer
which is then picked up by the GUI toolkit for display; the idea would be
to instead use the cairo-gl backend to directly render to the display).

I am not making a PR out of this backend *yet* mostly due to the dependency
on a very recent compiler, which I believe would not be acceptable to many,
and would probably require delving into the build scripts. Note that even
if I remove the C++17-isms from the codebase (which I'd rather not do --
"auto [x, y] = ..." is quite nice), pybind11 requires C++11 and suggests
using a C++14 compiler. Additionally, the backend depends on a number of
other large (current) PRs which do not seem close to get in (as listed in
the README). But I'd appreciate if you give it a try and give me some
feedback.

Antony
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-devel/attachments/20170629/a2d3dc60/attachment.html>

FWIW, the manylinux1 compiler (gcc 4.8.2) can only handle C++11. There
should be a manylinux2 coming along eventually (i.e., as soon as
someone steps up to do it, could be tomorrow, could be next year),
which will be able to use gcc 6.2.1. It looks like 6.2.1 has full
support for C++14 and partial support for C++17:
https://gcc.gnu.org/projects/cxx-status.html

-n

ยทยทยท

On Thu, Jun 29, 2017 at 12:49 AM, Antony Lee <antony.lee at berkeley.edu> wrote:

I am not making a PR out of this backend *yet* mostly due to the dependency
on a very recent compiler, which I believe would not be acceptable to many,
and would probably require delving into the build scripts. Note that even
if I remove the C++17-isms from the codebase (which I'd rather not do --
"auto [x, y] = ..." is quite nice), pybind11 requires C++11 and suggests
using a C++14 compiler.

--
Nathaniel J. Smith -- https://vorpus.org