2
votes

I'm trying to have an antialiased render of all text on my plots using Matplotlib. My plots are exported as pdf files. I allowed all parameters that say antialiased in my matplotlibrc file:

### MATPLOTLIBRC FORMAT

lines.antialiased   : True         # render lines in antialiased (no jaggies)
patch.antialiased   : True    # render patches in antialiased (no jaggies)
font.family         : serif
font.weight         : normal
font.size           : 12.0
font.serif          : Computer modern, DejaVu Serif, Bitstream Vera Serif,New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif

text.usetex         : True  # use latex for all text handling. The following fonts
text.latex.preamble :  \usepackage{amsmath},\usepackage{pgfplots},\usepackage[T1]{fontenc} 

text.antialiased : True # If True (default), the text will be antialiased.
                     # This only affects the Agg backend.


mathtext.fontset : cm # Should be 'dejavusans' (default),
                           # 'dejavuserif', 'cm' (Computer Modern), 'stix',
                           # 'stixsans' or 'custom'


axes.unicode_minus  : True    # use unicode for the minus symbol
                           # rather than hyphen.  See
                           # http://en.wikipedia.org/wiki/Plus_and_minus_signs#Character_codes

legend.loc           : best
legend.frameon       : False     # if True, draw the legend on a background patch
legend.framealpha    : 0.7      # legend patch transparency
legend.facecolor     : inherit  # inherit from axes.facecolor; or color spec
legend.edgecolor     : 0      # background patch boundary color
legend.fancybox      : False     # if True, use a rounded box for the
                             # legend background, else a rectangle

figure.autolayout : True  # When True, automatically adjust subplot
                        # parameters to make the plot fit the figure

And here follows a minimum non working example that generates an ugly figure:

import numpy as np
import matplotlib.pyplot as plt
plt.plot([1,1],[0,10], linewidth=2, label = r'I am a line')
leg = plt.legend(title=r'$The_{\text{legend}}$ : ' ,ncol=1)
leg._legend_box.align = 'left'
plt.xlabel(r'$D \text{(mm)}$')
plt.ylabel(r'Arbitrary unit')
plt.savefig('example.pdf')
plt.close()

This gives this figure:

Link to the pdf file, only valid 10 days

the figure

And when zoomed in we clearly see that the text is really pixelly out of math mode:

Figure zoomed in on legend

Figure zoomed on axis label

How could I avoid this ?

Also:

  • I know about svg, tikz and pgf export, but I would really like to have a file type that is easy to share with others,

  • I cannot switch all text to math mode because of typo rules. On plots, variables have to be rendered as maths objects and text as text ones,

  • adding \usepackage{lmodern, mathtools} in the LaTex preamble to use Latin Modern instead of Computer Modern does not work. Maybe because Matplotlib does not use LaTex to render the labels when out of math mode.

1
Your link to the figure is a png file, so I am not sure that zooming in is actually a problem in the pdf. Could you maybe provide a link to the actual pdf file? Secondly: If you do not want to use tikz/pgf, I guess you can try SVG file format...koffein
Thanks for your comment. I added a link to the pdf file, but I don't know how to add a permanent one, that's why I was using png figures. Also, I can't use svg files, I have colleagues that don't know how to open them.Ysen
I posted a question at tex.stackexchange.com/questions/405861/…. Please see the comment(s) from Skilmon for a possible remedy.Bill Bell
From the code example it seems you are refering to MathText, not Latex. Are you using Latex (i.e. did you miss some usetex=True somewhere)? In any case what would be the purpose of \text? Usually to get some upright font in mathmode you would use \mathrm{}.ImportanceOfBeingErnest
@ImportanceOfBeingErnest Following your question, I added all the uncommented lines from my matplotlibrc file :)Ysen

1 Answers

0
votes

Following the comment of ImprortanceOfBeingErnest,

Usually to get some upright font in mathmode you would use \mathrm{}

I have a working example of the code generating the figure, without changing the matplotlibrc:

import numpy as np
import matplotlib.pyplot as plt

plt.plot([1,1],[0,10], linewidth=2, label = r'$\mathrm{I \:  am \:  a  \: line}$')
leg = plt.legend(title=r'$The_{\mathrm{legend}}$ : ', ncol=1)
leg._legend_box.align = 'left'
plt.xlabel(r'$D \:  \mathrm{(mm)}$')
plt.ylabel(r'$\mathrm{Arbitrary \: unit}$')
plt.savefig('example.pdf')
plt.close()

This is really good for the rendering. But quite ugly in the code, where I always have to be in \mathrm{} mode to write, and add \: each time I want a space.

Then, my question becomes: Is there a way to avoid using \mathrm{} mode and still have a good figure? If not, then I'm quite happy with this.