diff --git a/doc/users/prev_whats_new/whats_new_1.5.rst b/doc/users/prev_whats_new/whats_new_1.5.rst index ec31bd887e0a..19610709498f 100644 --- a/doc/users/prev_whats_new/whats_new_1.5.rst +++ b/doc/users/prev_whats_new/whats_new_1.5.rst @@ -109,8 +109,8 @@ You can even multiply cyclers, which is like using `itertools.product()` on two or more property cycles. Remember to use parentheses if writing a multi-line `prop_cycle` parameter. -.. figure:: ../../gallery/color/images/sphx_glr_color_cycle_001.png - :target: ../../gallery/color/color_cycle.html +.. figure:: ../../tutorials/intermediate/images/sphx_glr_color_cycle_001.png + :target: ../../tutorials/intermediate/color_cycle.html :align: center :scale: 50 diff --git a/examples/animation/histogram.py b/examples/animation/histogram.py index 75adca125da5..365157172ab2 100644 --- a/examples/animation/histogram.py +++ b/examples/animation/histogram.py @@ -3,8 +3,7 @@ Animated histogram ================== -This example shows how to use a path patch to draw a bunch of -rectangles for an animated histogram. +Use a path patch to draw a bunch of rectangles for an animated histogram. """ import numpy as np @@ -14,8 +13,6 @@ import matplotlib.path as path import matplotlib.animation as animation -fig, ax = plt.subplots() - # Fixing random state for reproducibility np.random.seed(19680801) @@ -30,13 +27,23 @@ top = bottom + n nrects = len(left) -# here comes the tricky part -- we have to set up the vertex and path -# codes arrays using moveto, lineto and closepoly - -# for each rect: 1 for the MOVETO, 3 for the LINETO, 1 for the -# CLOSEPOLY; the vert for the closepoly is ignored but we still need -# it to keep the codes aligned with the vertices -nverts = nrects*(1 + 3 + 1) +############################################################################### +# Here comes the tricky part -- we have to set up the vertex and path codes +# arrays using ``plt.Path.MOVETO``, ``plt.Path.LINETO`` and +# ``plt.Path.CLOSEPOLY`` for each rect. +# +# * We need 1 ``MOVETO`` per rectangle, which sets the initial point. +# * We need 3 ``LINETO``'s, which tell Matplotlib to draw lines from +# vertex 1 to vertex 2, v2 to v3, and v3 to v4. +# * We then need one ``CLOSEPOLY`` which tells Matplotlib to draw a line from +# the v4 to our initial vertex (the ``MOVETO`` vertex), in order to close the +# polygon. +# +# .. note:: +# +# The vertex for ``CLOSEPOLY`` is ignored, but we still need a placeholder +# in the ``verts`` array to keep the codes aligned with the vertices. +nverts = nrects * (1 + 3 + 1) verts = np.zeros((nverts, 2)) codes = np.ones(nverts, int) * path.Path.LINETO codes[0::5] = path.Path.MOVETO @@ -50,13 +57,12 @@ verts[3::5, 0] = right verts[3::5, 1] = bottom -barpath = path.Path(verts, codes) -patch = patches.PathPatch( - barpath, facecolor='green', edgecolor='yellow', alpha=0.5) -ax.add_patch(patch) - -ax.set_xlim(left[0], right[-1]) -ax.set_ylim(bottom.min(), top.max()) +############################################################################### +# To animate the histogram, we need an ``animate`` function, which generates +# a random set of numbers and updates the locations of the vertices for the +# histogram (in this case, only the heights of each rectangle). ``patch`` will +# eventually be a ``Patch`` object. +patch = None def animate(i): @@ -68,5 +74,18 @@ def animate(i): verts[2::5, 1] = top return [patch, ] +############################################################################### +# And now we build the `Path` and `Patch` instances for the histogram using +# our vertices and codes. We add the patch to the `Axes` instance, and setup +# the `FuncAnimation` with our animate function. +fig, ax = plt.subplots() +barpath = path.Path(verts, codes) +patch = patches.PathPatch( + barpath, facecolor='green', edgecolor='yellow', alpha=0.5) +ax.add_patch(patch) + +ax.set_xlim(left[0], right[-1]) +ax.set_ylim(bottom.min(), top.max()) + ani = animation.FuncAnimation(fig, animate, 100, repeat=False, blit=True) plt.show() diff --git a/tutorials/intermediate/color_cycle.py b/tutorials/intermediate/color_cycle.py new file mode 100644 index 000000000000..ba463ade6bf9 --- /dev/null +++ b/tutorials/intermediate/color_cycle.py @@ -0,0 +1,125 @@ +""" +=================== +Styling with cycler +=================== + +Demo of custom property-cycle settings to control colors and other style +properties for multi-line plots. + +.. note:: + + More complete documentation of the ``cycler`` API can be found + `here `_. + +This example demonstrates two different APIs: + +1. Setting the default rc parameter specifying the property cycle. + This affects all subsequent axes (but not axes already created). +2. Setting the property cycle for a single pair of axes. + +""" +from cycler import cycler +import numpy as np +import matplotlib.pyplot as plt + +############################################################################### +# First we'll generate some sample data, in this case, four offset sine +# curves. +x = np.linspace(0, 2 * np.pi, 50) +offsets = np.linspace(0, 2 * np.pi, 4, endpoint=False) +yy = np.transpose([np.sin(x + phi) for phi in offsets]) + +############################################################################### +# Now ``yy`` has shape +print(yy.shape) + +############################################################################### +# So ``yy[:, i]`` will give you the ``i``-th offset sine curve. Let's set the +# default prop_cycle using :func:`matplotlib.pyplot.rc`. We'll combine a color +# cycler and a linestyle cycler by adding (``+``) two ``cycler``'s together. +# See the bottom of this tutorial for more information about combining +# different cyclers. +default_cycler = cycler('color', ['r', 'g', 'b', 'y']) \ + + cycler('linestyle', ['-', '--', ':', '-.']) + +plt.rc('lines', linewidth=4) +plt.rc('axes', prop_cycle=default_cycler) + +############################################################################### +# Now we'll generate a figure with two axes, one on top of the other. On the +# first axis, we'll plot with the default cycler. On the second axis, we'll +# set the prop_cycler using :func:`matplotlib.axes.Axes.set_prop_cycle` +# which will only set the ``prop_cycle`` for this :mod:`matplotlib.axes.Axes` +# instance. We'll use a second ``cycler`` that combines a color cycler and a +# linewidth cycler. +custom_cycler = cycler('color', ['c', 'm', 'y', 'k']) \ + + cycler('lw', [1, 2, 3, 4]) + +fig, (ax0, ax1) = plt.subplots(nrows=2) +ax0.plot(yy) +ax0.set_title('Set default color cycle to rgby') +ax1.set_prop_cycle(custom_cycler) +ax1.plot(yy) +ax1.set_title('Set axes color cycle to cmyk') + +# Add a bit more space between the two plots. +fig.subplots_adjust(hspace=0.3) +plt.show() + +############################################################################### +# Setting ``prop_cycler`` in the ``matplotlibrc`` file or style files +# ------------------------------------------------------------------- +# +# Remember, if you want to set a custom ``prop_cycler`` in your +# ``.matplotlibrc`` file or a style file (``style.mplstyle``), you can set the +# ``axes.prop_cycle`` property: +# +# ..code-block:: python +# +# axes.prop_cycle : cycler('color', 'bgrcmyk') +# +# Cycling through multiple properties +# ----------------------------------- +# +# You can add cyclers: +# +# .. code-block:: python +# +# from cycler import cycler +# cc = (cycler(color=list('rgb')) + +# cycler(linestyle=['-', '--', '-.'])) +# for d in cc: +# print(d) +# +# Results in: +# +# .. code-block:: python +# +# {'color': 'r', 'linestyle': '-'} +# {'color': 'g', 'linestyle': '--'} +# {'color': 'b', 'linestyle': '-.'} +# +# +# You can multiply cyclers: +# +# .. code-block:: python +# +# from cycler import cycler +# cc = (cycler(color=list('rgb')) * +# cycler(linestyle=['-', '--', '-.'])) +# for d in cc: +# print(d) +# +# Results in: +# +# .. code-block:: python +# +# {'color': 'r', 'linestyle': '-'} +# {'color': 'r', 'linestyle': '--'} +# {'color': 'r', 'linestyle': '-.'} +# {'color': 'g', 'linestyle': '-'} +# {'color': 'g', 'linestyle': '--'} +# {'color': 'g', 'linestyle': '-.'} +# {'color': 'b', 'linestyle': '-'} +# {'color': 'b', 'linestyle': '--'} +# {'color': 'b', 'linestyle': '-.'}