Matplotlib is a cornerstone tool for creating scientific visualizations, but preparing publication-ready figures requires attention to detail. While experienced researchers can produce polished plots, beginners often struggle with inconsistent or unprofessional results. In this post, I’ll share essential tips to elevate your Matplotlib figures for academic publishing.
Comply with Journal Requirements #
Before drafting figures, review your target journal's formatting guidelines. If you haven't selected a journal yet, follow the standards of leading publications in your field.
For example, Physical Review Letters (PRL) outlines its requirements on its Style Basics page. To locate these:
- Visit the PRL homepage.
- Navigate to the Authors section.
- Search for the keyword "figure".
Figure and Font Sizes #
Journal page dimensions vary, so adjust your figure size accordingly. For PRL, single-column figures should be 8.5 cm wide, while multi-column widths are 1.5 or 2 times this size. Since Matplotlib uses inches, convert millimeters to inches using:
# Use tight layout to ensure the figure is laid out in the given size
plt.rc("figure", autolayout=True)
ONE_MM = 1 / 25.4 # Convert mm to inches
fig = plt.figure(figsize=(85 * ONE_MM, 70 * ONE_MM)) # 85 mm x 70 mm
Avoid resizing figures within LaTeX like this:
\includegraphics[width=\textwidth]{figure.eps}
This scales text and line widths inconsistently across figures, creating a disjointed appearance.
Avoid manually stitching different subfigures produced with Matplotlib into a large figure. Fonts and line weights will mismatch, harming professionalism. Instead, use Matplotlib’s built-in subplots
or subfigure
utilities for unified layouts. By setting the figure size in Matplotlib the same as the final figure, you can easily control the consistent font size and make them the same across different figures, making them more professional. For example:
plt.rc("legend", fontsize=6)
plt.rc("font", size=8)
Customizing Matplotlib with style sheets and rcParams provides more details about different ways to customize Matplotlib styles.
Font Family #
Many journals specify font requirements. For instance, Nature mandates sans-serif fonts like Helvetica or Arial. It is crucial to know the requirement before you draft, as changing from a serif to a sans-serif font may ruin your layout.
File Formats #
Journals typically prefer vector formats (e.g., EPS, PDF) for line plots and diagrams. For raster images (e.g., photos), use 300–600 DPI.
Avoid composing different images into one big figure with LaTeX. Journals often need to present your figure on web pages, and one file per figure is the preferred practice. Use tools to merge the images into one figure file and export it in the preferred format by the journal.
SciencePlots is Not Magic #
The SciencePlots library simplifies styling with preconfigured themes:
import scienceplots
plt.style.use("science")
However, SciencePlots is not a magical solution, and the core logic is simple. In some cases, custom styles can yield better results.
For example, SciencePlots adds distracting top/right ticks, which clash with inset axes placed at the top right corner. Moreover, SciencePlots changes the color cycle in Matplotlib, which is unnecessary in most cases. The default color cycle has more colors and is suitable for complex plots.
Build Your Own Style #
Start with Matplotlib’s defaults, we will incrementally add style configurations to replicate key SciencePlots features while retaining flexibility:
First, add some basic adjustments to ticks and legends:
params_basic = {
"xtick.direction": "in", # Ticks point inward
"xtick.minor.visible": True, # Show minor ticks
"ytick.direction": "in",
"ytick.minor.visible": True,
"legend.frameon": False, # Remove legend border
}
with plt.style.context(params_basic):
fig = plt.figure(figsize=(85 * ONE_MM, 70 * ONE_MM), dpi=300)
plot_tanh(fig)
fig.suptitle("(b) Ticks inwards", x=0.03, ha="left")
plt.show()
Next, change the font from sans-serif to serif and adjust the line widths to be consistent with the font:
params_thin = {
"xtick.major.size": 3,
"xtick.major.width": 0.5,
"xtick.minor.size": 1.5,
"xtick.minor.width": 0.5,
"ytick.major.size": 3,
"ytick.major.width": 0.5,
"ytick.minor.size": 1.5,
"ytick.minor.width": 0.5,
"axes.linewidth": 0.5,
"grid.linewidth": 0.5,
"lines.linewidth": 1.0,
}
params_serif = {
**params_basic,
**params_thin,
"font.family": "serif",
"font.serif": ["cmr10"],
"axes.formatter.use_mathtext": True,
"mathtext.fontset": "cm",
}
with plt.style.context(params_serif):
fig = plt.figure(figsize=(85 * ONE_MM, 70 * ONE_MM), dpi=300)
plot_tanh(fig)
fig.suptitle("(c) Serif font", x=0.03, ha="left")
plt.show()
Alternatively, use LaTeX to render the text:
params_tex = {
**params_basic,
**params_thin,
"text.usetex": True,
}
with plt.style.context(params_tex):
fig = plt.figure(figsize=(85 * ONE_MM, 70 * ONE_MM), dpi=300)
plot_tanh(fig)
fig.suptitle(r"(d) \LaTeX\ and Line width adjust", x=0.03, ha="left")
plt.show()
In simple cases, the mathtext engine used by Matplotlib is sufficient for equations, avoiding the complexity of using LaTeX mode.
The above code demonstrates the main styles used by SciencePlots. You can save them as a name.mplstyle
file and use it in your future plots. I also encourage you to read the source code of SciencePlots for more details.
Additional Tips #
Official Matplotlib cheat sheets are super useful for beginners. You can quickly learn the main aspects and APIs of Matplotlib and stop asking AI for everything.
Transparent axes are useful when making posters. The figures drawn are not only used for journal articles, but may also be used in your posters and slides at academic conferences. With a transparent axis, you will have more freedom in choosing the background color of your poster.
Subfigures are a powerful tool for laying out complex figures and can do much more than subplots. When using subfigures, constrained layout is preferred over tight layout as it considers overlap between subfigures.
Choose color maps with care. Avoid the rainbow color map, and select the suitable color map based on your data. For example, avoid using diverging color maps if your data does not have a central value. Here, I quote the image from The misuse of colour in science communication.