Skip to content

Instantly share code, notes, and snippets.

@orome
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save orome/b4e5fd8a260a94820327 to your computer and use it in GitHub Desktop.
Save orome/b4e5fd8a260a94820327 to your computer and use it in GitHub Desktop.
Segmenting a wrapping matplotlib plot
# See -- http://stackoverflow.com/q/27138751/656912
from __future__ import division
import ephem
import matplotlib
import matplotlib.pyplot
import numpy
def segment_plot(x, y, ax, color='b', lw=1, ls='-', lims=[0, 24], thresh=0.95):
def unlink_wrap(dat, lims=lims, thresh=thresh):
jump = numpy.nonzero(numpy.abs(numpy.diff(dat)) > ((lims[1] - lims[0]) * thresh))[0]
lasti = 0
for ind in jump:
yield slice(lasti, ind + 1)
lasti = ind + 1
yield slice(lasti, len(dat))
def pad_segments(x, y, slc):
x_values = x[slc]
y_values = y[slc]
if slc.stop < len(x):
x_values = numpy.concatenate((x_values, [x[slc.stop + 1] + 24]))
y_values = numpy.concatenate((y_values, [y[slc.stop + 1]]))
if slc.start > 0:
x_values = numpy.concatenate(([x[slc.start - 1] - 24], x_values))
y_values = numpy.concatenate(([y[slc.start - 1]], y_values))
return x_values, y_values
for slc in unlink_wrap(x):
x_vals, y_vals = pad_segments(x, y, slc)
ax.plot(x_vals, y_vals, ls=ls, color=color, lw=lw)
base_date = ephem.Date(b'2014/11/25')
date_range = numpy.array(range(-182, 2*356))
fig, ax = matplotlib.pyplot.subplots()
for (planet, style) in [(ephem.Moon, {'color': '0.9'}),
(ephem.Sun, {'color': 'y', 'lw': '3'}),
(ephem.Mars, {'color': 'r'}),
(ephem.Jupiter, {'color': 'g'})]:
segment_plot(numpy.array([12*ep.ra/numpy.pi for ep in [planet(base_date + d) for d in date_range]]), date_range,
ax, **style)
ax.set(xlim=[0, 24])
ax.set(ylim=[min(date_range), max(date_range)])
@lkilcher
Copy link

Comments:

  1. According to the 'flat is better than nested' Python principal I believe it is bad style to define functions within functions. Instead, define functions 'flat' within a module, then import only the one you call (see my 'function' fork).
  2. You haven't passed the lims or thresh argument to your unlink_wrap(x) call. Thus, you won't be able to use different lims from the default values you define for that function.
  3. I also created a fork that implements this as a class. Here.

@orome
Copy link
Author

orome commented Nov 26, 2014

Excellent! Thanks for the improvements!

@lkilcher
Copy link

You're welcome! I didn't run either of my implementations to confirm they were bug-free, so comment on them if you have problems or questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment