Plotting ======== .. toctree:: :hidden: We often want to write a function which plots something. In order to be useful in a large variety of scenarios, a good library plotting function should be extremely flexible and support a large variety of options. We probably want to support basically the same set of options for virtually every plotting function we write. In order to avoid writing redundant code, we present the ``@plotter`` decorator, which is found in :mod:`lib5c.util.plotting`. Design principles ----------------- We expect a generic plotting function ``plot_fn()`` should take in some data and plot it to the default ``pyplot`` axis. We expect to be able to override some details about the plot, including what axis should be plotted on, the plot title, whether or not to add a legend, etc. Ideally, the function should return the axis it plotted on, which would allow the caller to make further modifications to the plot before saving to disk. However, many clients will probably want to just save the figure to disk as fast as possible, so an "automatic save" option should exist as well. Examples -------- We consider the plotting function ``plot_fn()``:: import matplotlib.pyplot as plt from lib5c.util.plotting import plotter @plotter def plot_fn(x, y, **kwargs): plt.scatter(x, y) Importantly, the ``@plotter`` API requires client functions to accept arbitrary ``**kwargs`` in their signature. A client may call :: ax = plot_fn(x, y) where the return value of ``plot_fn()`` will simply be the axis that was plotted on. To plot to a specific axis called ``ax``, the client may call :: ax = plot_fn(x, y, ax=ax) To automatically save the figure to disk, the client may call :: plot_fn(x, y, outfile='plot.png') Plots will be automatically saved at 300 dpi, but this can be overriden by calling :: plot_fn(x, y, outfile='plot.png', dpi=800) Plots will be styled with ``seaborn``, using the ``'ticks'`` axis style. To use a different ``seaborn`` style, the client can call :: plot_fn(x, y, style='darkgrid') The ``@plotter`` decorator will always automatically remove the ``seaborn`` styles after the call completes, allowing future plotting calls to look "normal". To avoid using the ``seaborn`` styles and stick with ``matplotlib`` defaults, the client can call :: plot_fn(x, y, style=None) The plot will be despined with ``sns.despine()`` by default. To disable this, the client can call :: plot_fn(x, y, despine=False) The decorated ``plot_fn()`` will accept a kwarg called ``legend``. By default, this kwarg is ``None``, which leaves all decisions about the legend in the hands of ``plot_fn()``. If ``plot_fn()`` adds a legend to the plot, but you wish to remove it, call :: plot_fn(x, y, legend=False) If ``plot_fn()`` does not add a legend, but you wish to have one, call :: plot_fn(x, y, legend=True) If the legend is really large and you wish it to be added outside the plot area, you can call :: plot_fn(x, y, legend='outside') Other minor adjustments can be made to the plot with the kwargs illustrated in the following example call:: plot_fn(x, y, xlim=(0, 10), ylim=(-1, 1), xlabel='number of cows', ylabel='relative change in grass', xticks=11, yticks=[-1, 0, 1], title='cows vs grass') Here we note that ``xticks`` and ``yticks`` can be passed as either an integer (in which case the specified axis will have that many evenly-spaced ticks) or as anything accepted by ``plt.xticks()`` (in our example, a list of tick locations).