I am having problems saving a figure created by matplotlib as a .eps or .ps when I enable usetex=True. This works when this is not enabled. Here's an example:
plt.plot([1,2,3], [1,2,3], 'b.')
plt.text(2,2,r'\textbf{(a)} \lambda_{1} value', usetex=True, fontsize=16, fontname='Times New Roman')
plt.savefig('check.eps')
I receive this error:
File "C:\Python27\lib\site-packages\matplotlib\backends\backend_ps.py", line 671, in draw_tex
thetext = 'psmarker%d' % self.textcnt
AttributeError: 'RendererPS' object has no attribute 'textcnt'
I also cannot set the font to Time New Roman using the text command when I enable usetex=True.
Even if it is a bit late, I would like to give an answer, if someone else searches for this error.
Saving eps files starts the RendererPS backend, which checks whether plt.rcParams['text.usetex'] is set to True to initialise its textcnt attribute. Since usetex is set only for the text object, the backend does not expect to have to handle LaTeX and throws an error when it tries to. These kind of inconsistencies concerning LaTeX rendering are sadly present in a number of places in matplotlib.
If you cannot achieve the text formatting with the standard matplotib functionality, one solution is to set usetex globally: plt.rcParams['text.usetex'] = True. This render all the text of the figure with LaTeX (e.g. also tick labels or axis labels). I would recommend to do this in any case, to have consistent visuals.
Concerning the font, the fontname argument only affects standard matplotlib formatting. For LaTeX rendering, you have to specify the font like you would do in LaTeX. To get a font like Times New Roman, you need to load the respective package e.g. mathptmx (the times package is deprecated) by plt.rcParams['text.latex.preamble'] = [r'\usepackage{mathptmx}']. Of course, the package has to be installed in your local LaTeX installation. The standard font family in matplotlib is sans-serif, so this has to be changed to serif with plt.rcParams['font.family'] = 'serif'.
The final code is:
import matplotlib.pyplot as plt
# LaTeX setup
plt.rcParams['text.latex.preamble'] = [r'\usepackage{mathptmx}'] # load times roman font
plt.rcParams['font.family'] = 'serif' # use serif font as default
plt.rcParams['text.usetex'] = True # enable LaTeX rendering globally
plt.plot([1,2,3], [1,2,3], 'b.')
plt.text(2,2,r'\textbf{(a)} $\lambda_1$ value', fontsize=16)
plt.savefig('check.eps')
Note, that you have to enclose the math variable in dollar signs $\lambda_1$, otherwise you get an error or warning in LaTeX. (Also, single character subscripts do not need to be enclosed in curly brackets).
As a side note: I encountered the same error, when trying to save a figure as eps after turning usetex off again.
Related
Summary
I am exporting matplotlib figures as PGF to use in LaTeX.
matplotlib seems to add a \sffamily addition to every text entry (axes labels, ticks, legend entries, annotations) when saving the figure as a PGF. This will stop it from properly inheriting the font from the global document font.
The text can inheret the font from the global document font if it is from the same family, but it will revert to the default sffamily font if the global font is from a different family.
Where I got to
I believe I have isolated the problem: if I edit the PGF document and simply remove the \sffamily part of any text entry, the problem no longer persists and the global font is inherited. The deletion doesn't prevent LaTeX from compiling it properly, and I get no errors.
Because of the above finding, I believe the problem has nothing to do with rcParams or any LaTeX preamble (both in python or in the actual LaTeX document).
MWE
I just tried it on the simplest possible plot and was able to reproduce the problem:
import matplotlib.pyplot as plt
fig = plt.figure()
plt.xlabel('a label')
fig.savefig('fig.pgf')
And pgf document will contain the following line:
\pgftext[x=3.280000in,y=0.240809in,,top]{\color{textcolor}\sffamily\fontsize{10.000000}{12.000000}\selectfont a label}%
so the \sffamily is added. Rendering this in LaTeX will force a sans-serif font. Removing the \sffamily and rendering it will allow it to inherit the font family.
TLDR
Is there a way to avoid the inclusion of a font family in the PGF output of matplotlib?
I cannot offer a solution but a workaround building on #samcarter's comment: You can redefine \sffamily locally, e.g.:
\documentclass{article}
\usepackage{pgf}
\usepackage{fontspec}
\setmainfont{DejaVu Serif}
\setsansfont{DejaVu Sans}
\setmonofont{DejaVu Sans Mono}
\begin{document}
Lorem ipsum {\sffamily Lorem ipsum}
\begin{center}
\renewcommand\sffamily{}
\input{fig.pgf}
\end{center}
Lorem ipsum {\sffamily Lorem ipsum}
\end{document}
Instead of center you can use any environment or \begingroup and \endgroup.
Building on https://matplotlib.org/users/pgf.html#font-specification you could use:
import matplotlib as mpl
import matplotlib.pyplot as plt
pgf_with_rc_fonts = {
"font.family": "serif",
}
mpl.rcParams.update(pgf_with_rc_fonts)
fig = plt.figure()
plt.xlabel('a label')
fig.savefig('fig.pgf')
This way \rmfamily is used instead of \sffamily.
There is another workaround by replacing the font specification with sed before importing the pgf file in your tex-document.
\documentclass{article}
\usepackage{pgf}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\usepackage{filecontents}
\begin{document}
\begin{figure}
\begin{filecontents*}{tmpfile.sed}
# sed command file
s/\\color{textcolor}\\sffamily\\fontsize{.*}{.*}\\selectfont //\end{filecontents*}
\immediate\write18{sed -i -f tmpfile.sed yourplot.pgf}
\import{yourplot.pgf}
\end{figure}
\end{document}
I am working on a software that solve an engineering problem. The software should printout the calculation for the user in a pretty mathematical expression format. I used Matplotlib,Latex and Sympy in PyQt and succeeded to do everything I wanted except for displaying the values of the variables in the form of a fracture (please see the picture below to understand what I mean). Also, I would like to know how to control the font size and style of the latex text(see the picture). below is a part of the code.
See this picture
def Calculate(self):
plt.rc('mathtext', fontset='cm')
self.right_column_stiffness = int(self.lineEdit_3.text())
self.left_column_stiffness = int(self.lineEdit_4.text())
self.beam_load = int(self.lineEdit_4.text())
w=self.beam_load*(1000/12)
g=386.1
self.mass = w/g
formula=r'm=\frac{w}{g}='
self.result_figure.text(.05, .85, r'${}$'.format(formula+latex(w)), fontsize=20)
[enter image description here][1]
self.result_canvas.draw()
There are two questions you have asked:
The font size of latex representation of fractions can be changed in two ways. First is to surround the fraction latex code with \displaystyle block.
formula = r'm={\displaystyle\frac{w}{g}}'
Other option is to change '${}$' to \[{}\] in the following line.
self.result_figure.text(.05, .85, r'\[{}\]'.format(formula+latex(w)), fontsize=20)
In order to print the values contained in variables as a fraction rather than the final answer, you will have to manually construct another latex text.
value = r'${{\displaystyle\frac{{{0}}}{{{1}}}}}$'.format(w,g)
Here is my example code:
import matplotlib.pyplot as plt
from matplotlib import rc # Added these two lines
rc('text', usetex=True)
formula = r'm=\frac{{w}}{{g}} = \frac{{{0}}}{{{1}}}'.format(100,20)
plt.plot( [0,1,2,3], [0,1,2,3], '.')
plt.text(1,1,r'\[{}\]'.format(formula),fontsize=20)
plt.show()
Which gives the following result
I am using PyPlot package from Julia language on macOS 10.13. Here is my code that generates the problem:
using PyPlot
PyPlot.svg(true)
function myplot()
my_font=matplotlib[:font_manager][:FontProperties](fname = "/System/Library/Fonts/Helvetica.ttc")
fig, ax = subplots()
ax[:plot](rand(10), rand(10), linewidth = 2)
for tick in ax[:xaxis][:get_major_ticks]()
tick[:label][:set_fontproperties](my_font)
end
for tick in ax[:yaxis][:get_major_ticks]()
tick[:label][:set_fontproperties](my_font)
end
savefig("figure.pdf")
end
myplot()
As you see, I need to change the font of the tick labels to Helvetica, which is available on my mac through the ttc file. The figure shows up normally in Jupyter Notebook. However, with savefig(), it does not work:
RuntimeError('TrueType font is missing table',)
I have already deleted ~/.matplotlib/fontList.py3k.cache and ~/.matplotlib/tex.cache. What do I still need to do to make savefig() work? Thanks!
I suggest you should change a font
matplotlib.rcParams['font.family'] = 'Calibri'
I want the ticks in matplotlib to be typeset using Computer Modern sans-serif. How do I do this?
I would have expected this would do the trick, but it doesn't:
mpl.rcParams['font.family'] = 'computer modern sans serif'
Try this:
mpl.rcParams['font.family'] = 'sans-serif'
mpl.rcParams['font.sans-serif'] = ['computer modern']
The font.family property has five values:
'serif' (e.g., Times),
'sans-serif' (e.g., Helvetica),
'cursive' (e.g., Zapf-Chancery),
'fantasy' (e.g., Western), and
'monospace' (e.g., Courier).
After setting the font family you provide a list of fonts for matplotlib to try to find in order.
noob here. I can't figure out the correct matplotlib line to use my newly loaded gillius font.
So I installed gillius font of the arkandis digital foundry on my machine
ttf-adf-gillius
here is the place i "think" it put it
usr/share/fonts/truetype/adf/GilliusADF-Regular.otf: Gillius
ADF:style=Regular
SO if I want to use it in my Python 3.4 program that imports matplotlib. I set the font_family= 'Gillius" and the program doesn't find it. What do I set the font family to to use my font please?
here is an example message from my python program
Warning (from warnings module):
File
"/usr/lib/python3/dist-packages/matplotlib/font_manager.py", line 1279
(prop.get_family(), self.defaultFamily[fontext]))
UserWarning: findfont: Font
family ['Gillius'] not found. Falling back to Bitstream Vera
Sans
Warning (from warnings module):
File
"/usr/lib/python3/dist-packages/matplotlib/font_manager.py", line 1289
UserWarning)
UserWarning: findfont: Could not match :family=Bitstream Vera
Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=20.0.
Returning /usr/share/matplotlib/mpl-data/fonts/ttf/cmmi10.ttf
I had already tried using the suggested link
How to use a (random) *.otf or *.ttf font in matplotlib?
but it didn't seem to do anything. My question is assuming the font is installed correctly what is the font family I should be entering to have matplotlib use it?
Ok I "think" this is a way to do it based on all the GREAT help I got on SO. thanks to all. I am new to matplotlib so if I screwed up happy to correct it.
import matplotlib
import matplotlib.font_manager as fm
from matplotlib import pyplot as plt
font = fm.FontProperties(
family = 'Gill Sans',
fname = '/usr/share/fonts/truetype/adf/GilliusADF-Regular.otf')
data = range(5)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.bar(data, data)
plt.ylabel('some y numbers')
plt.xlabel('some x numbers')
ax.set_yticklabels(ax.get_yticks(), fontproperties = font)
ax.set_xticklabels(ax.get_xticks(), fontproperties = font)
ax.set_title('this is a test of Gill sans font')
plt.show()