3. Matplotlib plots mit wissenschaftlichem Stil

In diesem Teil wird gezeigt wie man mit matplotlib einen Plot erzeugt der im Aussehen dem inoffiziellen Standard von wissenschaftlichen Veröffentlichungen entspricht.

Viele Teile davon sind aus dem Medium Beitrag von Rizky Maulana Nurhidayat entnommen. Die Einstellung der Zeilenbreite mit LaTeX kommt aus dem SciPy Coockbook

3.1. mit STIX font (LateX ähnlich, aber eher an Times New Roman angelehnt)

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator

# Schriftgroesse
fsize = 15 # Allgemein
tsize = 18 # Legende

# Grundeinstellungen (Ticks nach innen, Schriftart)
tdir = 'in'
major = 5.0 # Länge major ticks
minor = 3.0 # Länge minor ticks
lwidth = 0.8 # Dicke Rahmen
lhandle = 2.0 # Länge handle in Legende
plt.style.use('default')
plt.rcParams['mathtext.fontset'] = 'stix'
plt.rcParams['font.family'] = 'STIXGeneral'
plt.rcParams['font.size'] = fsize
plt.rcParams['legend.fontsize'] = tsize
plt.rcParams['xtick.direction'] = tdir
plt.rcParams['ytick.direction'] = tdir
plt.rcParams['xtick.major.size'] = major
plt.rcParams['xtick.minor.size'] = minor
plt.rcParams['ytick.major.size'] = major
plt.rcParams['ytick.minor.size'] = minor
plt.rcParams['axes.linewidth'] = lwidth
plt.rcParams['legend.handlelength'] = lhandle

# Bildgroesse
fig_width_pt = 400  # Get this from LaTeX using \showthe\columnwidth
inches_per_pt = 1.0/72.27               # Convert pt to inch
golden_mean = (np.sqrt(5)-1.0)/2.0    # Aesthetic ratio
fig_width = fig_width_pt*inches_per_pt  # width in inches
fig_height = fig_width*golden_mean      # height in inches

# Daten
x = np.arange(0., 10, .05)
y = x**2 - 20

# Plot
plt.figure(figsize=(fig_width,fig_height))   
plt.plot(x, y, label = r'$x^2$')

# Beschriftung
plt.legend(frameon=False)
plt.xlabel('$x$', labelpad = 10)
plt.ylabel('$\phi$', labelpad = 10);

# Achseneinteilung
plt.gca().xaxis.set_minor_locator(MultipleLocator(.5))
plt.gca().yaxis.set_minor_locator(MultipleLocator(10))

# Speichern
plt.savefig('scientific_plot_font-STIX.png', dpi = 300, pad_inches = .1, bbox_inches = 'tight')
../../_images/scientific_plots_2_0.png

3.2. mit CM (Computer Modern) - LaTeX Schrift

Verwendung von CM erfordert etwas mehr Aufwand, da diese nicht nativ vorhanden ist und zusätzlich mpl.rcParams['axes.unicode_minus']=False eingefügt werden muss um das Problem mit negativen Vorzeichen zu beheben

import matplotlib as mpl
import matplotlib.font_manager as font_manager
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator

# Schriftgroesse
fsize = 15 # Allgemein
tsize = 18 # Legende

# Grundeinstellungen (Ticks nach innen, Schriftart)
tdir = 'in'
major = 5.0 # Länge major ticks
minor = 3.0 # Länge minor ticks
lwidth = 0.8 # Dicke Rahmen
lhandle = 2.0 # Länge handle in Legende
plt.style.use('default')
plt.rcParams['font.family']='serif'
cmfont = font_manager.FontProperties(fname=mpl.get_data_path() + '/fonts/ttf/cmr10.ttf')
plt.rcParams['font.serif']=cmfont.get_name()
plt.rcParams['mathtext.fontset']='cm'
plt.rcParams['axes.unicode_minus']=False
plt.rcParams['font.size'] = fsize
plt.rcParams['legend.fontsize'] = tsize
plt.rcParams['xtick.direction'] = tdir
plt.rcParams['ytick.direction'] = tdir
plt.rcParams['xtick.major.size'] = major
plt.rcParams['xtick.minor.size'] = minor
plt.rcParams['ytick.major.size'] = major
plt.rcParams['ytick.minor.size'] = minor
plt.rcParams['axes.linewidth'] = lwidth
plt.rcParams['legend.handlelength'] = lhandle

# Bildgroesse
fig_width_pt = 400  # Get this from LaTeX using \showthe\columnwidth
inches_per_pt = 1.0/72.27               # Convert pt to inch
golden_mean = (np.sqrt(5)-1.0)/2.0    # Aesthetic ratio
fig_width = fig_width_pt*inches_per_pt  # width in inches
fig_height = fig_width*golden_mean      # height in inches

# Daten
x = np.arange(0., 10, .05)
y = x**2 - 20

# Plot
plt.figure(figsize=(fig_width,fig_height))   
plt.plot(x, y, label = r'$x^2$')

# Beschriftung
plt.legend(frameon=False)
plt.xlabel('$x$', labelpad = 10)
plt.ylabel('$\phi$', labelpad = 10);

# Achseneinteilung
plt.gca().xaxis.set_minor_locator(MultipleLocator(.5))
plt.gca().yaxis.set_minor_locator(MultipleLocator(10))

# Speichern
plt.savefig('scientific_plot_font-CM.png', dpi = 300, pad_inches = .1, bbox_inches = 'tight')
../../_images/scientific_plots_4_0.png

3.3. Mit LaTeX Rendering

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator

# Schriftgroesse
fsize = 15 # Allgemein
tsize = 18 # Legende

# Grundeinstellungen (Ticks nach innen, Schriftart)
tdir = 'in'
major = 5.0 # Länge major ticks
minor = 3.0 # Länge minor ticks
lwidth = 0.8 # Dicke Rahmen
lhandle = 2.0 # Länge handle in Legende
plt.style.use('default')
plt.rcParams['text.usetex'] = True # noch besser als nur Schriftart 'STIXGeneral' , aber sehr zeitintensiv da LaTeX Konvertierung
plt.rcParams['font.size'] = fsize
plt.rcParams['legend.fontsize'] = tsize
plt.rcParams['xtick.direction'] = tdir
plt.rcParams['ytick.direction'] = tdir
plt.rcParams['xtick.major.size'] = major
plt.rcParams['xtick.minor.size'] = minor
plt.rcParams['ytick.major.size'] = major
plt.rcParams['ytick.minor.size'] = minor
plt.rcParams['axes.linewidth'] = lwidth
plt.rcParams['legend.handlelength'] = lhandle

# Bildgroesse
fig_width_pt = 400  # Get this from LaTeX using \showthe\columnwidth
inches_per_pt = 1.0/72.27               # Convert pt to inch
golden_mean = (np.sqrt(5)-1.0)/2.0    # Aesthetic ratio
fig_width = fig_width_pt*inches_per_pt  # width in inches
fig_height = fig_width*golden_mean      # height in inches

# Daten
x = np.arange(0., 10, .05)
y = x**2 - 20

# Plot
plt.figure(figsize=(fig_width,fig_height))   
plt.plot(x, y, label = r'$x^2$')

# Beschriftung
plt.legend(frameon=False)
plt.xlabel('$x$', labelpad = 10)
plt.ylabel('$\phi$', labelpad = 10);

# Achseneinteilung
plt.gca().xaxis.set_minor_locator(MultipleLocator(.5))
plt.gca().yaxis.set_minor_locator(MultipleLocator(10))

# Speichern
plt.savefig('scientific_plot_LaTeX-render.png', dpi = 300, pad_inches = .1, bbox_inches = 'tight')
../../_images/scientific_plots_6_0.png