mpltex: A Tool for Creating Publication-Quality Plots

Reading time ~7 minutes

Creating a publication-quality plot is not an easy job. One needs to consider a dozen of factors.

  1. The figure size should be set explicitly to match journal specific value. For exmaple, journals published by American Chemical Society (ACS) allows a maximum 3.25-inch width figure for single-column and a maximum 7-inch width figure for double-column.
  2. The font family should be customized. Most of the time, “Times New Roman” is a safe choice. You should consult your journal author guide for more information.
  3. The font size also needs to be set properly.
  4. The linewdith of axis, axis ticks, line arts, the format of legend, the colors are all important factors affects the final looking of a plot.
  5. The file format of a figure should be chosen carefully. For most publishers, EPS is a good choice for line arts and other simple 2D arts, such as histograms, power spectra, bar charts, errorcharts, scatterplots.

Matplotlib, a Python 2D plotting library, is an amazingly flexible tool to create scientific plots. You can create various 2D arts with just a few lines of Python code. A plot created by the default settings of matplotlib looks like

matplotlib default output

The code to produce the above plot is

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import numpy as np
import matplotlib.pyplot as plt

def my_plot(t):
    fig, ax = plt.subplots(1)
    ax.plot(t, t, label='$t$')
    ax.plot(t, t**2, label='$t^2$')
    ax.plot(t, t**3, label='$t^3$')
    ax.plot(t, t**4, label='$t^4$')
    ax.plot(t, np.log(1+t), label='$\ln(1+t)$')
    ax.plot(t, t**(1./2), label='$t^{1/2}$')
    ax.plot(t, t**(1./3), label='$t^{1/3}$')

    ax.set_xlabel('$t$')
    ax.set_ylabel('$f(t)$')
    ax.legend(loc='best', ncol=2)
    fig.tight_layout(pad=0.1)
    fig.savefig('matplotlib-raw')

t = np.arange(0, 1.0+0.01, 0.01)
my_plot(t)
plt.close('all')

This plot is obviouly not ready for journal publication. The font size is too small. The line width for axes, ticks, and profiles are too thin. I also don’t like the border around the figure legend. And the line colors are too saturated and are not pleasing to look at.

To fix all these problems, I developed the Python package, mpltex, to customize the behavior of matplotlib for creating publication-quality plots. With mpltex, one can generate the following plot perfectly fufilled the requirements of ACS journals

mpltex line arts default

by just adding ONE LINE (besides the import package line import mpltex) before the definition of funciton my_plot in the above code block

@mpltex.acs_decorator

This line uses the decorator @acs_decorator from mpltex to decorating the function my_plot.

Currently, mpltex provides three decorators: @acs_decorator, @presentation_decorator, and @web_decorator. @acs_decorator is designed for creating plots for ACS journals. Journals from other publishers are yet to be supported. Hopefully, other decorators for this purpose will be available in the near future. @presentation_decorator creates plots in the PDF format and is suitable to be incorporated in presentation slides (especially convenient for Keynote). @web_decorator produces plots in the PNG format to be used in webpages.

In addition to these decorators, mpltex also provides a convenient generator, linestyle_generator, to generate various line styles to help create line arts with markers. The following codes convert the above plot into line profiles with different line styles and line markers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import numpy as np
import matplotlib.pyplot as plt

import mpltex

@mpltex.acs_decorator
def my_plot(t):
    fig, ax = plt.subplots(1)
    linestyles = mpltex.linestyle_generator()
    ax.plot(t, t, label='$t$', **linestyles.next())
    ax.plot(t, t**2, label='$t^2$', **linestyles.next())
    ax.plot(t, t**3, label='$t^3$', **linestyles.next())
    ax.plot(t, t**4, label='$t^4$', **linestyles.next())
    ax.plot(t, np.log(1+t), label='$\ln(1+t)$', **linestyles.next())
    ax.plot(t, t**(1./2), label='$t^{1/2}$', **linestyles.next())
    ax.plot(t, t**(1./3), label='$t^{1/3}$', **linestyles.next())

    ax.set_xlabel('$t$')
    ax.set_ylabel('$f(t)$')
    ax.legend(loc='best', ncol=2)
    fig.tight_layout(pad=0.1)
    fig.savefig('mpltex-acs-line-markers')

t = np.arange(0, 1.0+0.05, 0.05)
my_plot(t)
plt.close('all')

The resulted plot looks like

mpltex line arts with cycled colors, line styles and markers.

This plot is created by the default linestyle_generator. linestyle_generator has four arguments: colors, lines, markers, and hollow_styles. All are Python iterables (list, tuple, or other iterable objects). If you don’t want to cycle one of these, just pass an empty list or None to that argument. Below are examples of some most useful line-art styles.

Plot created by mpltex, cycling colors and line markers using

linestyles = mpltex.linestyle_generator(lines=[])
mpltex line arts with cycled colors and line markers

Plot created by mpltex, cycling colors and line styles using

linestyles = mpltex.linestyle_generator(markers=[])
mpltex line arts with cycled colors and line styles

Plot created by mpltex, cycling colors and filled markers using

linestyles = mpltex.linestyle_generator(lines=[], hollow_styles=[])
mpltex line arts with cycled colors and filled markers

Plot created by mpltex, cycling colors, line styles and filled markers using

linestyles = mpltex.linestyle_generator(hollow_styles=[])
mpltex line arts with cycled colors, line styles and filled markers

Plot created by mpltex, cycling colors and filled markers connected by solid lines using

linestyles = mpltex.linestyle_generator(lines=['-'], hollow_styles=[])
mpltex line arts with filled markers connected by solid lines

Plot created by mpltex, cycling all markers connected by solid lines using

linestyles = mpltex.linestyle_generator(lines=['-'])
mpltex line arts with markers connected by solid lines

And you can do something really cool by passing some specially designed combo arguments, such as

linestyles = mpltex.linestyle_generator(colors=[],
                                        lines=['-',':'],
                                        markers=['o','s'],
                                        hollow_styles=[False, False, True, True],)

This will create a black-white line art containing selected line styles and markers.

mpltex black-white line arts

Reference


Test PolyFTS with Polyorder

We will verify the [PolyFTS] calculation by comparing to the [Polyorder] results. The SCFT model we will test is miktoarm star block copo...… Continue reading

Polyorder Configuration File

Published on April 06, 2015