-
Notifications
You must be signed in to change notification settings - Fork 1
/
simplest_matplotlib.py
92 lines (79 loc) · 3.19 KB
/
simplest_matplotlib.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# absolute minimum implementations of the basic spaghetti plot designs
#
# written quickly by Gleicher on 10/17/2017
#
# this was meant to see how quickly I could get the basic designs in place
# I am not a matplotlib expert, so I did the simplest and first thing I could
# figure out. The plots are ugly - and the code is ugly. But it was fast to write.
#
# each of the 3 designs take a list of signals.
# there is no error checking
# everything is the defaults
#
# the one niceness: I resample the signals to length 200 - this gives smooth
# lasagna plots if the signals are shorter than 200, and does decent downsampling
# if M>200. (maybe decent - since to really get decent downsampling, I'd need to
# improve the spline fitter)
#
# the fact that these are all done using the subplot tools makes them very inflexible
# you basically cannot nest them into anything
# but this is part of the reason I dislike matplotlib
# I can't even figure out how to put the legend in a nice place (although, there is a nice
# command for making it)
#
import numpy
import matplotlib.pyplot as PLT
import scipy.interpolate as INTERP
def resample(signal, numsamples):
"""
utility routine - resamples a signal to have numsamples samples
if signal is short (relative to numsamples) it will interpolate
otherwise, some spline smoothing will happen
arguably, this should be linear interpolation for the upsampling
since we want to better preserve the shape of the data and avoid
ringing
:param signal: a 1D array to be resampled
:param numsamples: number of samples to have in the result
:return:
"""
u = INTERP.UnivariateSpline(numpy.linspace(0, numsamples, len(signal)), signal,
s=0 if len(signal) < numsamples else len(signal) / 2)
return numpy.array([u(v) for v in numpy.linspace(0, numsamples, numsamples)])
def colorfield(data, doresample=200):
"""
create world's simplest colorfield (lasagna plot)
truly ugly - but it works
:param data: must be a list of lists/arrays
:return:
"""
plots = PLT.subplots(len(data), sharex=True, sharey=False)
for i, d in enumerate(data):
dv = resample(d, doresample) if doresample else d
cf = plots[1][i].imshow([dv], aspect=5)
plots[1][i].colorfield = cf
plots[1][i].yaxis.set_visible(False)
return plots
def spaghetti(data, doresample=200):
"""
simplest spaghetti plot - basically uses matplotlib defaults
:param data: must be a list of lists/arrays
:return:
"""
# note: we need to use subplots to be consistent with the others
plots = PLT.subplots(1, 1)
for d in data:
dv = resample(d, doresample) if doresample else d
plots[1].plot(dv)
return plots
def smallMultiples(data, doresample=200):
"""
simplest small multiples of line graph - uses the matplotlib defaults
:param data: must be a list of lists/arrays
:param doresample: set to false if you don't want resampling (useful for testing
:return:
"""
plots = PLT.subplots(len(data), sharex=True, sharey=False)
for i, d in enumerate(data):
dv = resample(d, doresample) if doresample else d
plots[1][i].plot(dv)
return plots