Skip to content
Geoffrey Poore edited this page Jul 14, 2014 · 9 revisions

This page describes ways to make PythonTeX work with matplotlib more conveniently.

Saving figures and including them in your document

Suppose you have the following code in your document:

x=linspace(0, pi)
plt.plot(x, sin(x), label='sin(x)')
plt.plot(x, cos(x), label='cos(x)')

If you want to quickly view these plots in your document, you could call plt.legend() and plt.savefig('foo.pdf') and then write the LaTeX code to include a figure. To simplify this process the following helper functions may be useful. (Modify them to suit your needs!)

# Set the prefix used for figure labelsfig_label_prefix='fig'# Track figure numbers to create unique auto-generated namesfig_count=0defsavefig(name='', legend=False, fig=None, ext='.pdf'):
''' Save the current figure (or `fig`) to file using `plt.savefig()`. If called with no arguments, automatically generate a unique filename. Return the filename. '''# Get name (without extension) and extensionifnotname:
globalfig_count# `pytex.id` is a unique identifier for the session;# it's `<family>_<session>_<restart>`name='auto_fig_{}-{}'.format(pytex.id, fig_count)
fig_count+=1else:
iflen(name) >4andname[:-4] in ['.pdf', '.svg', '.png', '.jpg']:
name, ext=name.rsplit('.', 1)
# Get current figure if figure isn't specifiedifnotfig:
fig=gcf()
# Put a nice legend on top of the figure (you may need to adjust this!)# Only create legend if axis has labelsiflegendandlen(fig.gca().get_legend_handles_labels()[0]) !=0: foraxinfig.axes:
ifax.is_first_row():
box=ax.get_position()
ax.set_position([box.x0, box.y0, box.width, box.height*0.9])
leg=ax.legend(loc="upper center", bbox_to_anchor=(0.5, 1.04), ncol=3, bbox_transform=fig.transFigure, frameon=False)
fig.savefig(name+ext)
fig.clf()
returnnamedeflatex_environment(name, content='', option=''):
''' Simple helper function to write the `\begin...\end` LaTeX block. '''return'\\\\begin{%s}%s\n%s\n\\\\end{%s}'% (name, option, content, name)
deflatex_figure(name=None, caption='', label='', width=0.8):
'''' Auto wrap `name` in a LaTeX figure environment. Width is a fraction of `\textwidth`. '''ifnotname:
name=savefig()
content='\\\\centering\n'content+='\\\\includegraphics[width=%f\\\\textwidth]{%s}\n'% (width, name)
ifnotlabel:
label=nameifcaptionandnotcaption.rstrip().endswith('.'):
caption+='.'# `\label` needs to be in `\caption` to avoid issues in some casescontent+="\\\\caption{%s\\\\label{%s:%s}}\n"% (caption, fig_label_prefix, label)
returnlatex_environment('figure', content, '[htp]')

The above code block can be included in your document's preamble via

\begin{pythontexcustomcode}[begin]
...
\end{pythontexcustomcode}

Or you may store it in a file and import it in the usual way. Say you have a src directory alongside your document and the above code is in a file python_preamble.py:

\begin{pythontexcustomcode}[begin]{pylab}
# Might want sys.path.insert(1, '../src/') in some cases# But then it would probably be better to use virtualenvsys.path.append('../src/')
frompython_preambleimport*
\end{pythontexcustomcode}

The figure for the example considered at the beginning may now be created very simply:

\begin{pylabcode}
x=linspace(0, pi)
plt.plot(x, sin(x), label='sin(x)')
plt.plot(x, cos(x), label='cos(x)')
name=savefig()
fig=latex_figure(name)
\end{pylabcode}
\pylab{fig}

Of course, we could also just print the figure, using print(latex_figure()) at the end of the pylabcode environment or using \pylab{latex_figure()} after the end of the environment.

PGF backend

Matplotlib 1.2 has a new pgf backend. This may be useful when you want to create graphics that are compiled at the same time as the document (for better font integration, etc.).

Clone this wiki locally