Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib 2 inconsistent font

I updated Anaconda Python to the latest version (4.3), where they upgraded Matplotlib to version 2.

The upgrade has made some major changes to the default style (see here). And, while I really like some of those changes, I am not in agreement with a few of them.

Hence I did some modifications, as suggested in the link above:

#%matplotlib inline
#%config InlineBackend.figure_format = 'svg'
import scipy as sc
import matplotlib.pyplot as plt
import matplotlib

# http://matplotlib.org/users/dflt_style_changes.html
params = {'legend.fontsize': 18,
          'axes.labelsize': 18,
          'axes.titlesize': 18,
          'xtick.labelsize' :12,
          'ytick.labelsize': 12,
          'mathtext.fontset': 'cm',
          'mathtext.rm': 'serif',
          'grid.color': 'k',
          'grid.linestyle': ':',
          'grid.linewidth': 0.5,
         }
matplotlib.rcParams.update(params)

x = sc.linspace(0,100)
y = x**2
fig = plt.figure('Fig')
ax = fig.add_subplot(1, 1, 1)
lines = ax.semilogy(x, y)
ax.set_yticks([300], minor=True)
ax.yaxis.grid(True, which='minor')
ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter())
ax.tick_params(axis='y', pad=10)
ax.set_xlabel(r'$\mathrm{R_L}$')
ax.set_ylabel(r'$\sigma \int_l \; dx$')
#fig.savefig('./PNG/test.png', dpi=300, bbox_inches='tight')

Using Latex as the axes labels, as in the code above, results in a figure with inconsistent text on axes (see the following image).

enter image description here

How to get back to the previous behaviour (see the image below) or to a consistent font scheme?

enter image description here

EDIT: Using the Latex back-end I am able to get a good result, but it is extremely slow. Anyway, I think the internal back-end should be able to get a consistent output and switching to a different back-end is not a real solution, but more a workaround.

To use the latex back-end:

#%matplotlib inline
#%matplotlib notebook
#%config InlineBackend.figure_format = 'svg'
import scipy as sc
import matplotlib.pyplot as plt
import matplotlib

# http://matplotlib.org/users/dflt_style_changes.html
params = {'legend.fontsize': 18,
          'axes.labelsize': 18,
          'axes.titlesize': 18,
          'xtick.labelsize' :12,
          'ytick.labelsize': 12,
          'mathtext.fontset': 'cm',
          'mathtext.rm': 'serif',
          'grid.color': 'k',
          'grid.linestyle': ':',
          'grid.linewidth': 0.5,
         }
matplotlib.rcParams.update(params)
matplotlib.rcParams.update({'text.usetex':True, 'text.latex.preamble':[r'\usepackage{amsmath, newtxmath}']})

x = sc.linspace(0,100)
y = x**2
fig = plt.figure('Fig')
ax = fig.add_subplot(1, 1, 1)
lines = ax.semilogy(x, y)
ax.set_yticks([300], minor=True)
ax.yaxis.grid(True, which='minor')
ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter())
ax.tick_params(axis='y', pad=10)
ax.set_xlabel(r'$\mathrm{R_L}$')
ax.set_ylabel(r'$\sigma \int_l \; dx$')
#fig.savefig('./PNG/test.png', dpi=300, bbox_inches='tight')

The result with matplotlib 2 is:

enter image description here

The resulting plot with the older version is (still a bit different, maybe due to some latex differences):

enter image description here

But again, the desired result is what obtained from an older version of matplotlib and in displayed in figure 2.

like image 846
Alex Pacini Avatar asked Feb 15 '17 12:02

Alex Pacini


2 Answers

If consistency is the only issue, you can use a "Roman" style using the "Times" font. It is not necessary to use Latex via usetex. Instead simply use the STIX fontset, the Times font and serif mathtext.

import scipy as sc
import matplotlib.style
import matplotlib.pyplot as plt

params = {'legend.fontsize': 18,
          'axes.labelsize': 18,
          'axes.titlesize': 18,
          'xtick.labelsize' :12,
          'ytick.labelsize': 12,
          'grid.color': 'k',
          'grid.linestyle': ':',
          'grid.linewidth': 0.5,
          'mathtext.fontset' : 'stix',
          'mathtext.rm'      : 'serif',
          'font.family'      : 'serif',
          'font.serif'       : "Times New Roman", # or "Times"          
         }
matplotlib.rcParams.update(params)

x = sc.linspace(0,100)
y = x**2
fig = plt.figure('Fig')
ax = fig.add_subplot(1, 1, 1)
lines = ax.semilogy(x, y)

ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter())
ax.tick_params(axis='y', pad=10)
ax.set_yticks([300], minor=True)
ax.yaxis.grid(True, which='minor')
ax.set_xlabel(r'$\mathrm{R_L}$')
ax.set_ylabel(r'$\sigma \int_l \; dx$')
plt.tight_layout()
plt.show()

enter image description here

like image 104
ImportanceOfBeingErnest Avatar answered Nov 16 '22 10:11

ImportanceOfBeingErnest


From the link you did provide:

A ‘classic’ style sheet is provided so reverting to the 1.x default values is a single line of python

mpl.style.use('classic')

Adding this line

matplotlib.style.use('classic')

to your script should solve your problem.

I tested it on my python2.7/matplotlib 2, and it worked fine (i.e. I get back the matplotlib 1.x fonts).

like image 40
Eiffel Avatar answered Nov 16 '22 12:11

Eiffel