This guide is intended for Matplotlib<2.0; if you are using a newer version, please go here.
As someone who likes to use Python and Matplotlib, I have been struggling to make my plots look as nice as those created using Supermongo (SM) or IDL.
Here is a very basic SM macro that I wrote to plot this data, and the resulting figure:
And here is the same figure made using
this
python script and matplotlibrc
defaults:
Yikes! There are a number of problems with this figure, including: the text size is too small compared to the other elements, there are no minor tickmarks on the y-axis, the tickmarks are too small, and the fonts are mixed.
Luckily, this can be easily fixed.
Almost everything that I found needed adjustment can be changed from one's
matplotlibrc
file. This is what mine looks like:
# Set the backend, otherwise the figure won't show up. Note that this will # depend on your system setup; to see which backend is the default, # run "matplotlib.get_backend()" in the Python interpreter. backend : GTK3Agg # Increase the default DPI, and change the file type from png to pdf savefig.dpi : 300 savefig.extension : pdf # Simplify paths by removing "invisible" points, useful for reducing # file size when plotting a large number of points path.simplify : True # Instead of individually increasing font sizes, point sizes, and line # thicknesses, I found it easier to just decrease the figure size so # that the line weights of various components still agree figure.figsize : 4,4 # In this example I am *not* setting "text.usetex : True", therefore the # following ensures that the fonts in math mode agree with the regular ones. # font.family : serif mathtext.fontset : custom # Increase the tick-mark lengths (defaults are 4 and 2) xtick.major.size : 6 ytick.major.size : 6 xtick.minor.size : 3 ytick.minor.size : 3 # Increase the tick-mark widths as well as the widths of lines # used to draw marker edges to be consistent with the other figure # linewidths (defaults are all 0.5) xtick.major.width : 1 ytick.major.width : 1 xtick.minor.width : 1 ytick.minor.width : 1 lines.markeredgewidth : 1 # Have the legend only plot one point instead of two, turn off the # frame, and reduce the space between the point and the label legend.numpoints : 1 legend.frameon : False legend.handletextpad : 0.3
The final touch is adding minor tickmarks (this is done automatically for logarithmic axes,
but not for linear). This is not possible to set in matplotlibrc, so I just call
ax.minorticks_on()
on the axis object(s) in the figure.
import matplotlib.pyplot as plt import numpy as np x, y = np.loadtxt("data.txt", skiprows = 1, unpack = True) x = 10 ** x fig, ax = plt.subplots() ax.semilogx(x, y, 'o', label = "data") ax.legend(loc = 2, title = "Legend") ax.set_xlabel(r"Normal text vs. ${\rm math\, text}$") ax.set_ylabel(r"A B C $\alpha$ $\beta$ $\gamma$") # # Turn on minor ticks!! # ax.minorticks_on() fig.savefig("plot.pdf") plt.close(fig)
And here is the result:
Definitely an improvement!
Finally, a huge thanks to Gabriel-Dominique Marleau who made many helpful suggestions that improved this page.