python4oceanographers

Turning ripples into waves

Stick Plots with matplotlib

This short post consists of some notes on how to plot a stick plot with matplotlib. The function I used below is mostly based on this message from the mailing list.

The main differences are:

  • Plot customization via **kw.

  • Ensure that the user does not change the angles option to avoid breaking the stick plot.

  • Create a new figure or attach the stick plot to an existing axis.

In [3]:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.dates import date2num


def stick_plot(time, u, v, **kw):
    width = kw.pop('width', 0.002)
    headwidth = kw.pop('headwidth', 0)
    headlength = kw.pop('headlength', 0)
    headaxislength = kw.pop('headaxislength', 0)
    angles = kw.pop('angles', 'uv')
    ax = kw.pop('ax', None)
    
    if angles != 'uv':
        raise AssertionError("Stickplot angles must be 'uv' so that"
                             "if *U*==*V* the angle of the arrow on"
                             "the plot is 45 degrees CCW from the *x*-axis.")

    time, u, v = map(np.asanyarray, (time, u, v))
    if not ax:
        fig, ax = plt.subplots()
    
    q = ax.quiver(date2num(time), [[0]*len(time)], u, v,
                  angles='uv', width=width, headwidth=headwidth,
                  headlength=headlength, headaxislength=headaxislength,
                  **kw)

    ax.axes.get_yaxis().set_visible(False)
    ax.xaxis_date()
    return q

And here is how to use it.

In [4]:
from datetime import datetime, timedelta

x = np.arange(100, 110, 0.1)
start = datetime.now()
time = [start + timedelta(days=n) for n in range(len(x))]
u, v = np.sin(x), np.cos(x)
In [5]:
q = stick_plot(time, u, v)

ref = 1
qk = plt.quiverkey(q, 0.1, 0.85, ref,
                  "%s N m$^{-2}$" % ref,
                  labelpos='N', coordinates='axes')

_ = plt.xticks(rotation=70)
/usr/lib64/python3.3/site-packages/matplotlib/quiver.py:677: RuntimeWarning: divide by zero encountered in true_divide
  shrink = length / minsh
/usr/lib64/python3.3/site-packages/matplotlib/quiver.py:678: RuntimeWarning: invalid value encountered in multiply
  X0 = shrink * X0[np.newaxis, :]
/usr/lib64/python3.3/site-packages/matplotlib/quiver.py:679: RuntimeWarning: invalid value encountered in multiply
  Y0 = shrink * Y0[np.newaxis, :]

In [6]:
fig, ax = plt.subplots(figsize=(11, 2.75))

q = stick_plot(time, u, v, ax=ax, width=0.002, color='green')

ref = 1
qk = ax.quiverkey(q, 0.1, 0.85, ref,
                  "%s N m$^{-2}$" % ref,
                  labelpos='N', coordinates='axes')
In [7]:
q = stick_plot(time, u, v, angles='xy')

ref = 1
qk = ax.quiverkey(q, 0.1, 0.85, ref,
                  "%s N m$^{-2}$" % ref,
                  labelpos='N', coordinates='axes')
_ = plt.xticks(rotation=70)
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-7-0637860dd5cd> in <module>()
----> 1 q = stick_plot(time, u, v, angles='xy')
      2 
      3 ref = 1
      4 qk = ax.quiverkey(q, 0.1, 0.85, ref,
      5                   "%s N m$^{-2}$" % ref,

<ipython-input-3-eca382d3e9d7> in stick_plot(time, u, v, **kw)
     13 
     14     if angles != 'uv':
---> 15         raise AssertionError("Stickplot angles must be 'uv' so that"
     16                              "if *U*==*V* the angle of the arrow on"
     17                              "the plot is 45 degrees CCW from the *x*-axis.")

AssertionError: Stickplot angles must be 'uv' so thatif *U*==*V* the angle of the arrow onthe plot is 45 degrees CCW from the *x*-axis.
In [8]:
HTML(html)
Out[8]:

This post was written as an IPython notebook. It is available for download or as a static html.

Creative Commons License
python4oceanographers by Filipe Fernandes is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Based on a work at https://ocefpaf.github.io/.

Comments