1
1
import numpy as np
2
2
import matplotlib .pyplot as plt
3
+ import math
3
4
from . import records
4
5
from . import _headers
5
6
from . import annotations
6
7
7
8
# Plot a WFDB Record's signals
8
9
# Optionally, overlay annotation locations
9
- def plotrec (record = None , title = None , annotation = None , annch = [0 ], timeunits = 'samples' , returnfig = False ):
10
+ def plotrec (record = None , title = None , annotation = None , annch = [0 ], timeunits = 'samples' , returnfig = False , ecggrids = False ):
10
11
""" Subplot and label each channel of a WFDB Record.
11
12
Optionally, subplot annotation locations over selected channels.
12
13
@@ -70,12 +71,65 @@ def plotrec(record=None, title = None, annotation = None, annch = [0], timeunits
70
71
unitlabel = 'NU'
71
72
plt .ylabel (chanlabel + "/" + unitlabel )
72
73
74
+ # Show standard ecg grids if specified.
75
+ if ecggrids :
76
+ major_ticks_x , minor_ticks_x , major_ticks_y , minor_ticks_y = calc_ecg_grids (
77
+ record .p_signals [:,ch ], record .units [ch ], record .fs , t , timeunits )
78
+ ax .set_xticks (major_ticks_x )
79
+ ax .set_xticks (minor_ticks_x , minor = True )
80
+ ax .set_yticks (major_ticks_y )
81
+ ax .set_yticks (minor_ticks_y , minor = True )
82
+ ax .grid (which = 'both' )
83
+
73
84
plt .show (fig )
74
85
75
86
# Return the figure if requested
76
87
if returnfig :
77
88
return fig
78
89
90
+ # Calculate tick intervals for ecg grids
91
+ def calc_ecg_grids (signal , units , fs , t , timeunits ):
92
+
93
+ # 5mm 0.2s major grids, 0.04s minor grids
94
+ # 0.5mV major grids, 0.125 minor grids
95
+ # 10 mm is equal to 1mV in voltage.
96
+
97
+ # Get the grid interval of the x axis
98
+ if timeunits == 'samples' :
99
+ majorx = 0.2 * fs
100
+ minorx = 0.04 * fs
101
+ elif timeunits == 'seconds' :
102
+ majorx = 0.2
103
+ minorx = 0.04
104
+ elif timeunits == 'minutes' :
105
+ majorx = 0.2 / 60
106
+ minorx = 0.04 / 60
107
+ elif timeunits == 'hours' :
108
+ majorx = 0.2 / 3600
109
+ minorx = 0.04 / 3600
110
+
111
+ # Get the grid interval of the y axis
112
+ if units .lower ()== 'uv' :
113
+ majory = 500
114
+ minory = 125
115
+ elif units .lower ()== 'mv' :
116
+ majory = 0.5
117
+ minory = 0.125
118
+ elif units .lower ()== 'v' :
119
+ majory = 0.0005
120
+ minory = 0.000125
121
+ else :
122
+ raise ValueError ('Signal units must be uV, mV, or V to plot the ECG grid.' )
123
+
124
+
125
+ major_ticks_x = np .arange (0 , upround (max (t ), majorx ), majorx )
126
+ minor_ticks_x = np .arange (0 , upround (max (t ), majorx ), minorx )
127
+
128
+ major_ticks_y = np .arange (downround (min (signal ), majory ), upround (max (signal ), majory ), majory )
129
+ minor_ticks_y = np .arange (downround (min (signal ), majory ), upround (max (signal ), majory ), minory )
130
+
131
+ return (major_ticks_x , minor_ticks_x , major_ticks_y , minor_ticks_y )
132
+
79
133
# Check the validity of items used to make the plot
80
134
# Return the x axis time values to plot for the record (and annotation if any)
81
135
def checkplotitems (record , title , annotation , annch , timeunits ):
@@ -233,3 +287,11 @@ def checkannplotitems(annotation, title, timeunits):
233
287
raise TypeError ("The 'title' field must be a string" )
234
288
235
289
return plotvals
290
+
291
+ # Round down to nearest <base>
292
+ def downround (x , base ):
293
+ return base * round (float (x )/ base )
294
+
295
+ # Round up to nearest <base>
296
+ def upround (x , base ):
297
+ return base * math .ceil (float (x )/ base )
0 commit comments