Use lualatex in mathplotlib without pgf backend - matplotlib

basically the title is the question:
I would like to use lualatex for all the text handling in a matplotlib plot without using the pgf backend.
I need fontenc package and customized fonts to have identical fonts in plots and in my latex documents but do not want to use the pgf backend.
Is there a hidden option somewhere?
The context is the following: I have a mycommands.sty file where all my defind \newcommand for math are stored. I use some specific fonts for, e. g., \mathscr{p}, which is not possible (small letter) without the fontenc package.
Now I want to use these custom commands in different places (legend, labels, title, ...) in the plot and have them work and look exactly the same as in the document I write and compile with lualatex.
The only point why it is not possible is that matplotlib internally uses pdflatex for the compilation which gives me errors when using fontenc and therefore some of my commands do not work.
Thanks.

Related

Sphinx latex class package option clash

I'm using Sphinx and restructured text to generate a PDF with tables in it. I'd like to specify the table option to the xcolor package so I can use \rowcolors to achieve an alternating row color scheme.
Reviewing Sphinx documentation for adding packages, it appears I should use the preamble key in the latex_elements configuration to add my custom latex:
\usepackage[table]{xcolor}
\rowcolors{2}{blue!10}{white}
However, when I do that, I get the error:
! LaTeX Error: Option clash for package xcolor
Looking at the .tex file output by Sphinx, it appears the clash comes from \usepackage[,numfigreset=2,mathnumfig]{sphinx}, because the sphinx.sty class requires the xcolor package, which gets imported without any options.
I can get this to work by manually editing the .tex output and moving my \usepackage[table]{xcolor} above the sphinx package import line, but there doesn't appear to be any way to achieve that via my conf.py.
Sphinx added an extrapackages key that places custom latex prior to the hyperref package import, but that is still after the sphinx package import.
I've also tried the passoptionstopackages key, which adds the latex \PassOptionsToPackage{table}{xcolor}, but this also doesn't work when it comes after the initial import of xcolor.
I think I have three main questions:
Is there another way to achieve an alternating row coloring scheme for tables in a PDF with Sphinx?
Does anyone know why the extrapackages key only places package import above hyperref and not others?
Is there a way to include custom latex or override Sphinx-generated latex above where extrapackages places it?

Using matplotlib with latex mode with non-default fonts

I am using Windows 10 with Anaconda and Spyder 4. When using matplotlib, I would like to use the font Proxima Nova and render with LaTeX.
If in my matplotlibrc file I specify
font.family : Proxima Nova
then the figure renders with the font Proxima Nova. This means that the font is installed on my system (as it is) and matplotlib can use it. However, if in the matplotlibrc file I also specify
text.usetex: True
then, even though I have specified Proxima Nova as the font, the figure renders in the default LaTeX font, which I guess is Computer Modern.
I have tried
matplotlib.font_manager._rebuild()
In the source code file and also have tried specifying the fonts in the source code file and not in the matplotlibrc file. However I always get the same result. I have also followed all the advice on this help page, including making sure that latex, dvipng and ghostscript are all the PATH variable. However nothing seems to work.
I would like to note that I can use Proxima Nova separately when compiling Latex documents, so that should not be an issue either.
How can I get matplotlib to be able to use a non-default font and render with LateX at the same time?
After some further investigation, I was able to get to use Proxima Nova with Latex, although there are still some outstanding issues.
The main issue is that if the font Proxima Nova is used with Latex, one needs to use Lualatex and not plain Latex. Here is the Matplotlib instruction on using matplotlib with Lualatex.
The key to getting things to work was this post.
At the very beginning of my .py file, I have the following code:
import matplotlib as mpl
mpl.use("pgf")
mpl.rcParams.update({
'font.family': 'sans-serif',
'text.usetex': True,
'pgf.rcfonts': False,
'pgf.texsystem': 'lualatex',
'pgf.preamble': r'\usepackage{fontspec} \setmainfont{Proxima Nova}',
})
The code above should be placed at the very top of the code, above any other imports.
The problem, however is that this solution works only after performing the following steps:
Delete the .matplotlib/tex.cache folder and restart spyder
Replace 'font.family': 'sans-serif' and \setmainfont{Proxima Nova} with 'font.family': 'serif' and \setmainfont{Times New Roman} respectively. Run python once.
Revert back to 'font.family': 'sans-serif' and
\setmainfont{Proxima Nova} and run python again.
The output with the correct font is produced.
Unless the above 4 steps are performed, the output is compiled with the default DejaVu Sans font and not with Proxima Nova. I am not sure why...
After getting help on the matplotlib github forum, I was pointed to the following solution:
mpl.rcParams.update({
'font.family': 'sans-serif',
'text.usetex': True,
'pgf.rcfonts': False,
'pgf.texsystem': 'lualatex',
'pgf.preamble': r'\usepackage{fontspec} \setsansfont{Proxima Nova}',
})
In other words you need to use setsansfont in stead of setmainfont. You can see the matplotlib forum page here.

Using mathtext parser to output a svg file

Context
I'm looking for a simple way to import properly typeset mathematics (with LaTeX) into blender. A solution for this has already been given. But that means getting out of blender, using multiple tools and then going back to blender and importing the whole thing.
Blender comes with Python and can import svg
I'd like to find an other way and blender has a set of powerful tools based on Python. I was thinking: can I make Python parse some TeX input and then generate a svg (virtual) file inside blender. That would solve the problem.
matplotlib "emulates" TeX
It is possible to install any Python library and use it inside blender. So this made me think of a possible "hack" of matplotlib.
mathtext is a module that provides a parser for strings with TeX-like syntax for mathematical expressions. svg is one of the available "backends".
Consider the following snippet.
import matplotlib.mathtext as mathtext
parser = mathtext.MathTextParser('svg')
t = parser.parse(r'$\int_{0}^{t} x^2 dx = \frac{t^3}{3}$')
t is a tuple that has all the information needed. But I can't find a way (in the backend api) to convert it to a (virtual) svg file.
Any ideas?
Thanks
Matplotlib needs a figure (and currently also a canvas) to actually be able to render anything. So in order to produce an svg file whose only content is a text (a mathtext formula) you still need a figure and a canvas and the text needs to actually reside inside the figure, which can be achieved by fig.text(..).
Then you can save the figure to svg via fig.savefig(..). Using the bbox_inches="tight" option ensures the figure to be clipped to the extent of the text. And setting the facecolor to a transparent color removes the figure's background patch.
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.figure import Figure
fig = Figure(figsize=(5, 4), dpi=100)
canvas = FigureCanvasAgg(fig)
fig.text(.5, .5, r'$\int_{0}^{t} x^2 dx = \frac{t^3}{3}$', fontsize=40)
fig.savefig("output.svg", bbox_inches="tight", facecolor=(1,1,1,0))

Two different fonts in one inline object while creating PDF

Is it technically possible to use two different font in the same
DrawHTMLTextBox while using Debenu Quick PDF Library 10?
Is it possible with any other libraries which can be used in a PHP
project (Not preferred)?
Currently it is not possible to use two different fonts in the string that you pass to the DrawHTMLTextBox function in Debenu Quick PDF Library. If you want to use a different font for different parts of the string you'll need to use DrawHTMLText instead and change the font using SetHTMLNormalFont prior to each section of the string being drawn.
Using this method you'll need to keep track of the width and height of the text you're drawing yourself but you can do that using the GetHTMLTextHeight, GetHTMLTextWidth and GetHTMLTextLineCount.

Can I distribute just one extra font file with a matplotlib application?

I’m writing a Python program that uses matplotlib. I’d like to use a font that isn’t included with matplotlib. (Well, I want to use Lucida Grande, which is included in OS X, but matplotlib can’t read the .dfont file directly so I need to distribute my own .ttf font.)
It seems like matplotlib only ever looks in one directory for fonts: mpl-data/fonts. It’s possible to tweak matplotlib’s configuration to change where the mpl-data directory is, but it doesn’t seem to be possible to specify more than one such directory in which fonts may be found. Is that accurate?
(It would be possible for me to put the font in my system’s global mpl-data directory, but it feels wrong for an application to muck around with a globally-used directory like that. And I sure as hell don’t want to include the entire mpl-data-plus-one-file with my application.)
One possibility is to expand on the response provided here which uses the matplotlib font manager module. Specifically, it looks like you can specify the absolute path to your font with the fname argument to matplotlib.font_manager.FontProperties (see the docs here: http://matplotlib.org/api/font_manager_api.html#matplotlib.font_manager.FontProperties)
Modifying the previous SO response (to a slightly simpler question) below, this is certainly worth a try if you can specify the absolute path to the ttf font file in your workflow. I've used a built-in MacOS font below (and that works), but maybe try substituting your particular absolute path & font to see if it works.
import matplotlib
matplotlib.use( "agg" ) #some backend sensitivity explained in previous SO response
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
fig, ax = plt.subplots()
#specify the absolute path to your font file:
absolute_path_to_ttf_file = '/opt/X11/share/fonts/TTF/VeraSe.ttf'
prop = fm.FontProperties(fname=absolute_path_to_ttf_file)
ax.set_title('Text in a cool font', fontproperties=prop, size=40)
plt.show()
plt.savefig('test.png')