11import numpy as np
22import matplotlib .pyplot as plt
3+ import math
34from . import records
45from . import _headers
56from . import annotations
67
78# Plot a WFDB Record's signals
89# 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 ):
1011 """ Subplot and label each channel of a WFDB Record.
1112 Optionally, subplot annotation locations over selected channels.
1213
@@ -70,12 +71,65 @@ def plotrec(record=None, title = None, annotation = None, annch = [0], timeunits
7071 unitlabel = 'NU'
7172 plt .ylabel (chanlabel + "/" + unitlabel )
7273
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+
7384 plt .show (fig )
7485
7586 # Return the figure if requested
7687 if returnfig :
7788 return fig
7889
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+
79133# Check the validity of items used to make the plot
80134# Return the x axis time values to plot for the record (and annotation if any)
81135def checkplotitems (record , title , annotation , annch , timeunits ):
@@ -233,3 +287,11 @@ def checkannplotitems(annotation, title, timeunits):
233287 raise TypeError ("The 'title' field must be a string" )
234288
235289 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