Using plt.ginput in Jupyter!¶

ginput is a powerful tool to get numerical information from a plot! However it is a little tricky using it in Jupyter Notebooks. Let´s see.

Check this Satckoverflow query... I learnt from it!

https://stackoverflow.com/questions/41403406/matplotlib-use-of-ginput-on-jupyter-matplotlib-notebook

image.png

In [34]:
import pickle
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

Tidal amplitude¶

In this example, let´s use a hourly time series of tidal amplitude for a period of one year. It was obtained using the Hilbert Transform, showed in another notebook.

The goal is to sample the peaks of spring and neap tides... It could be done with some algorithm to find inflexions in the function, but there is some noisy signal... could be filtered, etc... but here we are, let´s do it by the 'not-so-elegant-way'.

Loading and checking the data¶

In [10]:
with open ('hilbert_envelope.pkl', 'rb') as io:
    p = pickle.load(io)

time = p['tempo']
amplitude = p['amplitude']

plt.figure(figsize=(10,2))
plt.plot(time, amplitude)
Out[10]:
[<matplotlib.lines.Line2D at 0x1c97d6c0f10>]
No description has been provided for this image

From the Stack, we need use the 'TkAgg', whatever it is. I learn that this can cause some error... specially if you are repeating the process... notice that we import the 'matplotlib' without the 'pyplot'!

In [11]:
import matplotlib
matplotlib.use('TkAgg')

When we run the cell below, the plot will open in a external window from the Jupyter. Sometimes you need to look for it. This new window you can resize and work with mouse digitizing the points you want to acquire. Help yourself with 'ginput' docstring!

During the digitizing, each new point will be showed after 'click'...

When finished, you need press 'enter' to end the digitizing.

image.png

In [29]:
# %matplotlib qt

# plt.figure(figsize=(10,2))
# plt.plot(time, amplitude)
# pts = plt.ginput(-1, -1)

When using the 'ginput', we are storing the digitized points in the variable 'pts', which is a tuple.
In order to save the work, we need convert it to array and pickle for further use... after we are happy with the results, best to comment the code related with the digitizing!

Here I run once to digitize the 'springs' peaks, and a second time to digitize the 'neaps' peaks, pickling after...

After pickling, comment the code!

In [28]:
# saving the springs
# springs = np.array(pts)
# with open('springs.pkl', 'wb') as io:
#     pickle.dump(springs, io)


# saving the neaps
# neaps = np.array(pts)
# with open('neaps.pkl', 'wb') as io:
#     pickle.dump(neaps, io)

After pickling, to preserve the work, we load again as it was any other data! Obviously, this could be done in a separated notebook...

In [32]:
with open('springs.pkl', 'rb') as io:
    springs = pickle.load(io)

with open('neaps.pkl', 'rb') as io:
    neaps = pickle.load(io)

The digitizing capture the coordinates 'numerically', so, we need to create the datetime stamps in order to do a new plot

In [35]:
springs_time = mdates.num2date(springs[:,0])
neaps_time = mdates.num2date(neaps[:,0])

Finally...

In [37]:
%matplotlib inline

plt.figure(figsize=(10,2))
plt.plot(time, amplitude)

plt.plot(springs_time, springs[:,1], 'o')
plt.plot(neaps_time, neaps[:,1], 'o')
Out[37]:
[<matplotlib.lines.Line2D at 0x1c910eef2d0>]
No description has been provided for this image