Skip to content

Commit 1325615

Browse files
committed
finish ecggrids
1 parent 4b7b522 commit 1325615

File tree

4 files changed

+43
-398
lines changed

4 files changed

+43
-398
lines changed

README.rst

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -319,18 +319,17 @@ Plotting Data
319319

320320
::
321321

322-
plotrec(record=None, title = None, annotation = None, annch = [0], timeunits='samples', returnfig=False)
322+
plotrec(record=None, title = None, annotation = None, annch = [0], timeunits='samples', figsize=None, returnfig = False, ecggrids=[]):
323323

324324
Example Usage:
325325

326326
::
327327

328328
import wfdb
329-
record = wfdb.rdsamp('sampledata/100', sampto = 15000)
330-
annotation = wfdb.rdann('sampledata/100', 'atr', sampto = 15000)
329+
record = wfdb.rdsamp('sampledata/100', sampto = 3000)
330+
annotation = wfdb.rdann('sampledata/100', 'atr', sampto = 3000)
331331

332-
wfdb.plotrec(record, annotation = annotation, title='Record 100 from MIT-BIH Arrhythmia Database', timeunits = 'seconds')
333-
332+
wfdb.plotrec(record, annotation = annotation, title='Record 100 from MIT-BIH Arrhythmia Database', timeunits = 'seconds', figsize = (10,4), ecggrids = 'all')
334333

335334
Input Arguments:
336335

@@ -339,7 +338,9 @@ Input Arguments:
339338
- ``annotation`` (default=None): An Annotation object. The annsamp attribute locations will be overlaid on the signal.
340339
- ``annch`` (default=[0]): A list of channels on which to plot the annotation samples.
341340
- ``timeunits`` (default='samples'): String specifying the x axis unit. Allowed options are: 'samples', 'seconds', 'minutes', and 'hours'.
341+
- ``figsize`` (default=None): Tuple pair specifying the width, and height of the figure. Same as the 'figsize' argument passed into matplotlib.pyplot's figure() function.
342342
- ``returnfig`` (default=False): Specifies whether the figure is to be returned as an output argument
343+
- ``ecggrids`` (default=[]): List of integers specifying channels in which to plot ecg grids. May be set to [] for no channels, or 'all' for all channels. Major grids at 0.5mV, and minor grids at 0.125mV. All channels to be plotted with grids must have units equal to 'uV', 'mV', or 'V'.
343344

344345
Output argument:
345346
- ``figure``: The matplotlib figure generated. Only returned if the 'returnfig' option is set to True.

devtests.ipynb

Lines changed: 5 additions & 378 deletions
Large diffs are not rendered by default.

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
# Versions should comply with PEP440. For a discussion on single-sourcing
2121
# the version across setup.py and the project code, see
2222
# https://packaging.python.org/en/latest/single_source_version.html
23-
version='1.0.5',
23+
version='1.0.6',
2424

2525
description='The WFDB Python Toolbox',
2626
long_description=long_description,

wfdb/plots.py

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
# Plot a WFDB Record's signals
99
# Optionally, overlay annotation locations
10-
def plotrec(record=None, title = None, annotation = None, annch = [0], timeunits='samples', returnfig = False, ecggrids=False):
10+
def plotrec(record=None, title = None, annotation = None, annch = [0], timeunits='samples', figsize=None, returnfig = False, ecggrids=[]):
1111
""" Subplot and label each channel of a WFDB Record.
1212
Optionally, subplot annotation locations over selected channels.
1313
@@ -21,17 +21,23 @@ def plotrec(record=None, title = None, annotation = None, annch = [0], timeunits
2121
- annch (default=[0]): A list of channels on which to plot the annotation samples.
2222
- timeunits (default='samples'): String specifying the x axis unit.
2323
Allowed options are: 'samples', 'seconds', 'minutes', and 'hours'.
24+
- figsize (default=None): Tuple pair specifying the width, and height of the figure. Same as the 'figsize' argument
25+
passed into matplotlib.pyplot's figure() function.
2426
- returnfig (default=False): Specifies whether the figure is to be returned as an output argument
27+
- ecggrids (default=[]): List of integers specifying channels in which to plot ecg grids. May be set to [] for
28+
no channels, or 'all' for all channels. Major grids at 0.5mV, and minor grids at 0.125mV. All channels to be
29+
plotted with grids must have units equal to 'uV', 'mV', or 'V'.
2530
2631
Output argument:
2732
- figure: The matplotlib figure generated. Only returned if the 'returnfig' option is set to True.
2833
2934
Example Usage:
3035
import wfdb
31-
record = wfdb.rdsamp('sampledata/100', sampto = 15000)
32-
annotation = wfdb.rdann('sampledata/100', 'atr', sampto = 15000)
36+
record = wfdb.rdsamp('sampledata/100', sampto = 3000)
37+
annotation = wfdb.rdann('sampledata/100', 'atr', sampto = 3000)
3338
34-
wfdb.plotrec(record, annotation = annotation, title='Record 100 from MIT-BIH Arrhythmia Database', timeunits = 'seconds')
39+
wfdb.plotrec(record, annotation = annotation, title='Record 100 from MIT-BIH Arrhythmia Database',
40+
timeunits = 'seconds', figsize = (10,4), ecggrids = 'all')
3541
"""
3642

3743
# Check the validity of items used to make the plot
@@ -40,8 +46,12 @@ def plotrec(record=None, title = None, annotation = None, annch = [0], timeunits
4046

4147
siglen, nsig = record.p_signals.shape
4248

49+
# Expand ecg grid channels
50+
if ecggrids == 'all':
51+
ecggrids = range(0, record.nsig)
52+
4353
# Create the plot
44-
fig=plt.figure()
54+
fig=plt.figure(figsize=figsize)
4555

4656
for ch in range(nsig):
4757
# Plot signal channel
@@ -70,14 +80,17 @@ def plotrec(record=None, title = None, annotation = None, annch = [0], timeunits
7080
else:
7181
unitlabel='NU'
7282
plt.ylabel(chanlabel+"/"+unitlabel)
73-
83+
7484
# Show standard ecg grids if specified.
75-
if ecggrids:
85+
if ch in ecggrids:
7686

87+
auto_xlims = ax.get_xlim()
88+
auto_ylims= ax.get_ylim()
89+
7790
major_ticks_x, minor_ticks_x, major_ticks_y, minor_ticks_y = calc_ecg_grids(
78-
min(record.p_signals[:,ch]), max(record.p_signals[:,ch]), record.units[ch], record.fs, max(t), timeunits)
91+
auto_ylims[0], auto_ylims[1], record.units[ch], record.fs, auto_xlims[1], timeunits)
7992

80-
min_x, max_x = 0, np.max(t)
93+
min_x, max_x = np.min(minor_ticks_x), np.max(minor_ticks_x)
8194
min_y, max_y = np.min(minor_ticks_y), np.max(minor_ticks_y)
8295

8396
for tick in minor_ticks_x:
@@ -89,6 +102,10 @@ def plotrec(record=None, title = None, annotation = None, annch = [0], timeunits
89102
for tick in major_ticks_y:
90103
ax.plot([min_x, max_x], [tick, tick], c='#bababa', marker='_')
91104

105+
# Plotting the lines changes the graph. Set the limits back
106+
ax.set_xlim(auto_xlims)
107+
ax.set_ylim(auto_ylims)
108+
92109
plt.show(fig)
93110

94111
# Return the figure if requested
@@ -130,11 +147,11 @@ def calc_ecg_grids(minsig, maxsig, units, fs, maxt, timeunits):
130147
raise ValueError('Signal units must be uV, mV, or V to plot the ECG grid.')
131148

132149

133-
major_ticks_x = np.arange(0, upround(maxt, majorx), majorx)
134-
minor_ticks_x = np.arange(0, upround(maxt, majorx), minorx)
150+
major_ticks_x = np.arange(0, upround(maxt, majorx)+0.0001, majorx)
151+
minor_ticks_x = np.arange(0, upround(maxt, majorx)+0.0001, minorx)
135152

136-
major_ticks_y = np.arange(downround(minsig, majory), upround(maxsig, majory), majory)
137-
minor_ticks_y = np.arange(downround(minsig, majory), upround(maxsig, majory), minory)
153+
major_ticks_y = np.arange(downround(minsig, majory), upround(maxsig, majory)+0.0001, majory)
154+
minor_ticks_y = np.arange(downround(minsig, majory), upround(maxsig, majory)+0.0001, minory)
138155

139156
return (major_ticks_x, minor_ticks_x, major_ticks_y, minor_ticks_y)
140157

@@ -298,7 +315,7 @@ def checkannplotitems(annotation, title, timeunits):
298315

299316
# Round down to nearest <base>
300317
def downround(x, base):
301-
return base * round(float(x)/base)
318+
return base * math.floor(float(x)/base)
302319

303320
# Round up to nearest <base>
304321
def upround(x, base):

0 commit comments

Comments
 (0)