Getting semi-transparent text with matplotlib+pgf backend when compiling in LateX - python

So I am using the pgf backendin matplotlib to include some automatically compiled references to some other parts of my Tex documents (figures, bibliography) in my TeX document.
import matplotlib
matplotlib.use('pgf')
import matplotlib.pyplot as plt
plt.figure()
plt.txt(0.0,0.5,r'Some text compiled in latex \cite{my_bib_tag}')
plt.savefig("myfig.pgf", bbox_inches="tight", pad_inches=0)
Then in my tex document I have the lines:
\usepackage[dvipsnames]{xcolor}
%yada yada yada
\begin{figure}
\input{myfig.pgf}
\end{figure}
It is working great but when I try to add some transparency to the text it doesn't work. For instance when setting:
plt.txt(0.0,0.5,r'Some text compiled in latex \cite{my_bib_tag}', alpha=0.5)
The text appears unchanged, and if I try to do it in the compilation by using \textcolorfrom the xcolor package (or any other commands in LateX, like the transparent package) I get parsing errors when compiling the Python.
I tried escaping characters but somehow I cannot make it work.
plt.txt(0.0,0.5,r'\textcolor{gray}{Some text compiled in latex \cite{my_bib_tag}}', alpha=0.5)
#raise ValueError !Undefined Control Sequence
EDIT 1: I tried adding the required package in the preamble, but it does not work when saving to pgf (with the pgf backend), it works using the Agg backend (I think it is expected behavior). But I need to save it in pgf to have the dynamic parsing of references.
import matplotlib
import matplotlib.pyplot as plt
matplotlib.rcParams["text.usetex"] = True
matplotlib.rcParams["text.latex.preamble"].append(r'\usepackage[dvipsnames]{xcolor}')
matplotlib.verbose.level = 'debug-annoying'
plt.figure()
plt.text(0.0,0.5,r'\textcolor{gray}{Some text compiled in latex \cite{my_bib_tag}}', alpha=0.5)
#works in .png, does not work in .pgf
#plt.savefig("myfig.png", bbox_inches="tight", pad_inches=0)
EDIT 2: A work around is to use the color param in plt.text but what if I would like to use more complicated LateX styling...

Thanks to #ImportanceOfBeingErnest I finally made it work with the pgf backend:
import matplotlib
matplotlib.use('pgf')
import matplotlib.pyplot as plt
pgf_with_custom_preamble = {
"text.usetex": True, # use inline math for ticks
"pgf.rcfonts": False, # don't setup fonts from rc parameters
"pgf.preamble": [
"\\usepackage[dvipsnames]{xcolor}", # load additional packages
]
}
matplotlib.rcParams.update(pgf_with_custom_preamble)
plt.figure()
plt.text(0.0,0.5,r'\textcolor{gray}{Some text compiled in latex \cite{my_biblio_tag}}')
plt.savefig("myfig.pgf", bbox_inches="tight", pad_inches=0)

Related

matplotlib pgf pdfcomment preamble causing blank extra page

I am trying to add some tooltips to a matplotlib pdf file. To do this I am using pgf so I can add "pdfcomment" in the preamble. However, when I add pdfcomment to the preamble I get a blank extra page. This does not happen with other packages like xcolor and hyperref (for example).
Here is the code as I'm using it for testing, which I got from this discussion:
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.use("pgf")
pgf_with_pdflatex = {
"pgf.texsystem": "pdflatex",
"pgf.preamble": r"\usepackage{pdfcomment}",
}
mpl.rcParams.update(pgf_with_pdflatex)
fig = plt.figure(figsize=(4.5,2.5))
for i in range(5):
plt.text(i,i,r"\pdftooltip{\rule{0.3cm}{0.3cm}}{(%d,%d)}" % (i,i))
plt.plot(range(5), linewidth = 10)
plt.savefig("tooltips.pdf")
plt.close()
Which works, except that it makes an extra page. Below is a minimalist version which reproduces the problem.
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.use("pgf")
mpl.rcParams["pgf.texsystem"] = "pdflatex"
#mpl.rcParams["pgf.preamble"] = r"\usepackage{pdfcomment}" # uncomment to get blank page
plt.plot(range(5), linewidth = 10)
plt.savefig("tooltips.pdf")
plt.close()
Essentially if you uncomment that one line you will get an extra blank page as output which I don't want. Below are two example screenshots that I get, one with the extra page and one without (all I changed was uncommenting the line).
As extra information, my pdflatex version is:
pdfTeX 3.14159265-2.6-1.40.20 (TeX Live 2019/Debian)
python3 version is:
Python 3.8.10
Matplotlib version is:
3.3.2
Please help and please be kind, this is my first time posting a question.
Edit: as requested here is the intermediate LaTeX file. This is in the form of a pgf file which one would include in a tex document I think. I wasn't sure how to get the .tex directly.
It isn't pretty, but I think I found a work around. Here is the modified minimal version which only outputs a single page. Based on the comment by samcarter_is_at_topanswers.xyz, the problem is with matplotlib not LaTeX, so I just include a pdflatex call in the script. Here is the minimal working version:
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.use("pgf")
mpl.rcParams["pgf.texsystem"] = "pdflatex"
mpl.rcParams["pgf.preamble"] = r"\usepackage{pdfcomment}"
plt.plot(range(5), linewidth = 10, zorder = 10)
plt.savefig("tooltips.pgf")
plt.close()
import subprocess
with open("tooltips.tex", "w") as f:
f.write(r"""
\documentclass{standalone}
\usepackage{pgf}
\usepackage{pdfcomment}
\begin{document}
\input{tooltips.pgf}
\end{document}
""")
subprocess.run(["pdflatex", "tooltips.tex"])
Note that matplotlib outputs a .pgf file instead of a .pdf file.

Non-italicized tick labels with pgf in matplotlib

I am using the pgf backend in matplotlib 1.5.3 to produce publication-quality figures. Here is how I set up the plotting script.
import matplotlib as mpl
mpl.use('pgf')
pgf_with_latex = { # setup matplotlib to use latex for output
"pgf.texsystem": "pdflatex", # change this if using xetex or lautex
"text.usetex": True, # use LaTeX to write all text
"font.family": "sans-serif",
"font.sans-serif": "Bitstream Vera Sans, Helvetica, Computer Modern Sans Serif",
"pgf.preamble": [
r"\usepackage[utf8x]{inputenc}", # use utf8 fonts because your computer can handle it :)
r"\usepackage[T1]{fontenc}", # plots will be generated using this preamble
r"\usepackage{textcomp}",
r"\usepackage{sfmath}", # sets math in sans-serif
]
}
mpl.rcParams.update(pgf_with_latex)
import matplotlib.pyplot as plt
def newfig():
plt.clf()
fig = plt.figure(figsize=(4, 2))
ax = fig.add_subplot(111)
return fig, ax
fig, ax = newfig()
ax.set_xlabel("Some x-label text")
plt.gcf().tight_layout()
plt.savefig(os.getcwd() + "/test.pdf")
plt.savefig(os.getcwd() + "/test.eps")
I am using the package sfmath to set all math environments in sans-serif. At the end I save in .pdf and .eps format. Here's the problem: While the pdfclearly uses sans-serif font everywhere, the eps file uses serif for all tick labels (not axis labels)! When I modify my LaTeX template to use sfmath it does not change the tick labels.
How can I prevent the epsfrom using serif font in the tick labels?
Edit: After a good day of experimenting, the only (barely) satisfying solution I found was to use .tiff as format, since this is also allowed by the journal. eps just seems to have problems and always turns out different than the pdf or other image formats.

How to use pgf backend to include hyperlink in matplotlib pdf plot?

I wish to include a hyperlink in a matplotlib plot, which I can output as a pdf (to later be inserted into a LaTeX document).
I know this kind of question has been asked, but the solutions which I've seen only seem to give rise to some error. I'm currently attempting to use the pgf backend, and my code is as below:
import matplotlib
matplotlib.use('pgf')
import matplotlib.pyplot as plt
plt.rc('text', usetex=True)
plt.rc('font', family='serif')
matplotlib.rcParams['pgf.preamble'] = [r'\usepackage{hyperref}', ]
x = (1,2,3,4)
y = (1,4,9,16)
plt.figure()
plt.plot(x,y,'bo')
plt.title(r"\href{http://www.google.com}{Test Link}",color='blue')
plt.savefig('Test.pdf')
plt.close()
However, I keep getting the following error:
matplotlib.backends.backend_pgf.LatexError:
LaTeX returned an error, probably missing font or error in preamble
Not sure why this is, any help would be greatly appreciated.

Can I integrate MathJax into a Python program?

This might be a silly question, but is it possible to merge MathJax into Python code? Many times I've wished the program output would look more neat, and honestly MathJax looks awesome.
I know MathJax runs on Javascript, yet I have not given up hope. If the answer is no, are there some simple modules to use instead?
For example, if:
1.234 / e^23 [and] (I^-)_(aq) +I _(2(s)) -> (I^-)_3(aq)
could be formatted as:
,
that would be ideal.
I can only presume that maybe you want to output something to the display for printing. Hence the common usage in Python is probably Matplotlib (albeit Gnuplot is a good alternative that is python compatible).
If you create a blank plot using Matplotlib then you can input normal plain LaTeX maths instructions (near identical to MathJax):
A small example:
import matplotlib
matplotlib.use('TkAgg')
import pylab
import matplotlib.pyplot as plt
from matplotlib import rc
plt.clf()
plt.rc('text', usetex=True)
plt.rcParams["figure.figsize"] = (8, 5)
plt.rc('font', **{'family':'serif', 'serif':['Computer Modern Roman'], 'size': 16})
plt.axis("off")
plt.text(0.5, 0.5, "Maths $e = mc^2$")
gives the following output
which can trivially be saved, as a .pdf, and then the apparent graininess of my screenshot is removed.
Following the answer of oliversm, one can use the class mathtext of mathplotlib:
from matplotlib import mathtext, font_manager
import matplotlib as mpl
mpl.rcParams['savefig.transparent'] = True
#texFont = font_manager.FontProperties(size=30, fname="./OpenSans-Medium.ttf")
texFont = font_manager.FontProperties(size=30, family='serif', math_fontfamily='cm')
mathtext.math_to_image(r"Maths $e = mc^2$", "output.png", prop=texFont, dpi=300, format='png')

Matplotlib 'eps' export using savefig generates error when using TeX in figure

I am trying to export a figure which is rendered using TeX. I use the following minimal example code to accomplish this:
import matplotlib.pyplot as plt
from matplotlib import rc
rc('text', usetex=True)
fig, ax = plt.subplots()
fig.savefig('plot.eps', format='eps')
This generates an error:
RuntimeError: ghostscript was not able to process your image.
Here is the full report generated by ghostscript:
(it doesn't actually provide the full report)
Now if i render without TeX then everything works fine:
rc('text', usetex=False)
Also rendering with TeX and outputting to PNG or PDF works fine aswell.
Anyone know what is going on?

Categories