예제 #1
0
    def add_composite_ddT_max(self, index, signal):

        # Calculate second derivative
        _, second = hb.get_derivatives(signal)

        # Look at interval between st_start and t peak
        st_start_t_interval = range(self.ST_start.data[index],
                                    self.T.data[index])

        # Locate T''max
        if len(st_start_t_interval) / 6 > 1:
            second_peaks = find_peaks(5 * second[st_start_t_interval],
                                      distance=len(st_start_t_interval) / 6)[0]
        else:
            second_peaks = find_peaks(5 * second[st_start_t_interval])[0]

        if len(second_peaks) == 0:
            second_peaks = [self.T.data[index]] if np.isnan(
                np.median(second[st_start_t_interval])) else [
                    np.median(second[st_start_t_interval])
                ]

        # Look at interval between big hump and t peak
        low_mag_interval = range(
            self.ST_start.data[index] + int(second_peaks[0]),
            self.T.data[index])

        # Locate T''max
        if len(low_mag_interval) / 2 > 1:
            second_low_mag_peaks = find_peaks(5 * second[low_mag_interval],
                                              distance=len(low_mag_interval) /
                                              2)[0]
        else:
            second_low_mag_peaks = find_peaks(5 * second[low_mag_interval])[0]

        if len(second_low_mag_peaks) == 0:
            # Add data
            if len(st_start_t_interval) == 0:
                st_start_t_interval = [self.ST_start.data[index]]
            self.ddT_max.data.append(st_start_t_interval[0] +
                                     int(second_peaks[-1]))

        else:
            # Add data
            self.ddT_max.data.append(low_mag_interval[0] +
                                     int(second_low_mag_peaks[-1]))
예제 #2
0
    def update_plot(self):
        # Update index
        self.i_text.set_text("Heartbeat: " + str(self.index + 1) + "/" + str(len(self.peaks.R.data) - 1))

        self.signal = hb.normalize(self.peaks.signal[range(self.peaks.P.data[self.index], self.peaks.R.data[self.index + 1])])

        # Pass through a Low pass
        self.smoothed_signal = hb.lowpass_filter(signal = self.signal,
                                            cutoff_freq = self.cutoff_freq)

        # Calculate first derivative
        self.first, _ = hb.get_derivatives(self.smoothed_signal)

        # Update cross hairs
        self.switch_signal(None)

        # Plot ECG, Phono and Seismo
        self.signal_line.set_data(range(len(self.signal)), self.signal_amp_slider.val * self.signal)
        self.smooth_signal_line.set_data(range(len(self.signal)), self.signal_amp_slider.val * self.smoothed_signal)
        self.first_line.set_data(range(len(self.signal)), (self.first_amp_slider.val * 5*self.first) + self.first_height_slider.val + 1)
       
        self.ax.set_xlim(0, len(self.signal))

        # T Peak
        self.T_point.set_offsets((self.peaks.T.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.T.data[self.index] - self.peaks.P.data[self.index]]))
        self.T_text.set_position((self.peaks.T.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.T.data[self.index] - self.peaks.P.data[self.index]] + 0.2))

        # ST Start Peak
        self.ST_start_point.set_offsets((self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index]]))
        self.ST_start_text.set_position((self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index]] + 0.2))

        # T''max Peak
        self.dT_point.set_offsets((self.peaks.dT.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.dT.data[self.index] - self.peaks.P.data[self.index]]))
        self.dT_text.set_position((self.peaks.dT.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.dT.data[self.index] - self.peaks.P.data[self.index]] + 0.2))
        
        # # T''max Peak
        # self.ddT_point.set_offsets((self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index]]))
        # self.ddT_text.set_position((self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index]] + 0.2))

        self.fig.canvas.draw()
예제 #3
0
    def add_composite_ST_segment(self, index, signal):

        # Calculate second derivative
        smoothed_first, second = hb.get_derivatives(signal)

        # Look at interval between s and t peak
        s_t_interval = range(self.S.data[index], self.T.data[index])

        # Find start of S-T segment
        if len(s_t_interval) > 1:
            self.ST_start.data.append(self.S.data[index] + np.argmin(second[
                s_t_interval[:int(0.15 * len(s_t_interval))]]))
        else:
            self.ST_start.data.append(self.S.data[index])

        # Look at interval between st_start and t peak
        st_start_t_interval = range(self.ST_start.data[index],
                                    self.T.data[index])

        # Find end of S-T segment
        if len(st_start_t_interval) / 6 > 1:
            smoothed_first_peaks = find_peaks(
                smoothed_first[st_start_t_interval],
                distance=len(st_start_t_interval) / 6)[0]
        else:
            smoothed_first_peaks = find_peaks(
                smoothed_first[st_start_t_interval])[0]

        if len(smoothed_first_peaks) > 1:
            st_end = int(smoothed_first_peaks[-2])
        elif len(smoothed_first_peaks) == 1:
            st_end = smoothed_first_peaks[0]
        else:
            st_end = ((self.T.data[index] - self.ST_start.data[index]) /
                      2) + self.ST_start.data[index]

        self.ST_end.data.append(self.ST_start.data[index] + st_end)
예제 #4
0
    def update_plot(self):
        # Update index
        self.i_text.set_text("Composite: " + str(self.index + 1) + "/" +
                             str(len(self.composite_peaks.composites)))

        # Load composite signals
        self.time, self.signal, self.seis, self.phono = self.composite_peaks.composites[
            self.index]
        _, self.second = hb.get_derivatives(self.signal)

        # Update cross hairs
        self.switch_signal(None)

        # Plot ECG, Phono and Seismo
        self.signal_line.set_data(range(len(self.signal)), self.signal)
        self.second_line.set_data(
            range(
                self.composite_peaks.ST_start.data[self.index],
                int(
                    np.median([
                        self.composite_peaks.T.data[self.index],
                        len(self.signal)
                    ]))), 2 + 15 * self.second[range(
                        self.composite_peaks.ST_start.data[self.index],
                        int(
                            np.median([
                                self.composite_peaks.T.data[self.index],
                                len(self.signal)
                            ])))])
        self.seis_line.set_data(range(len(self.seis)), self.seis)
        self.phono_line.set_data(range(len(self.phono)), self.phono)
        self.ax.set_xlim(0, len(self.signal))

        # Q Peaks
        self.q_point.set_offsets(
            (self.composite_peaks.Q.data[self.index],
             self.signal[self.composite_peaks.Q.data[self.index]]))
        self.q_text.set_position(
            (self.composite_peaks.Q.data[self.index],
             self.signal[self.composite_peaks.Q.data[self.index]] + 0.2))

        # QM Seismo
        self.qm_seis_point.set_offsets(
            (self.composite_peaks.QM_seis.data[self.index],
             self.seis[self.composite_peaks.QM_seis.data[self.index]]))
        self.qm_seis_text.set_position(
            (self.composite_peaks.QM_seis.data[self.index],
             self.seis[self.composite_peaks.QM_seis.data[self.index]] + 0.2))

        # QM Phono
        self.qm_phono_point.set_offsets(
            (self.composite_peaks.QM_phono.data[self.index],
             self.phono[self.composite_peaks.QM_phono.data[self.index]]))
        self.qm_phono_text.set_position(
            (self.composite_peaks.QM_phono.data[self.index],
             self.phono[self.composite_peaks.QM_phono.data[self.index]] + 0.2))

        # T''max Peak
        self.ddT_max_point.set_offsets(
            (self.composite_peaks.ddT_max.data[self.index],
             self.signal[self.composite_peaks.ddT_max.data[self.index]]))
        self.ddT_max_text.set_position(
            (self.composite_peaks.ddT_max.data[self.index],
             self.signal[self.composite_peaks.ddT_max.data[self.index]] + 0.2))

        # TM Seismo
        self.tm_seis_point.set_offsets(
            (self.composite_peaks.TM_seis.data[self.index],
             self.seis[self.composite_peaks.TM_seis.data[self.index]]))
        self.tm_seis_text.set_position(
            (self.composite_peaks.TM_seis.data[self.index],
             self.seis[self.composite_peaks.TM_seis.data[self.index]] + 0.2))

        # TM Phono
        self.tm_phono_point.set_offsets(
            (self.composite_peaks.TM_phono.data[self.index],
             self.phono[self.composite_peaks.TM_phono.data[self.index]]))
        self.tm_phono_text.set_position(
            (self.composite_peaks.TM_phono.data[self.index],
             self.phono[self.composite_peaks.TM_phono.data[self.index]] + 0.2))

        self.fig.canvas.draw()
예제 #5
0
    def plot_signals(self):
        # Create figure
        self.fig, self.ax = plt.subplots()

        # Load composite signals
        self.time, self.signal, self.seis, self.phono = self.composite_peaks.composites[
            self.index]
        _, self.second = hb.get_derivatives(self.signal)

        # Plot ECG, Phono and Seismo
        self.signal_line, = self.ax.plot(self.signal,
                                         linewidth=1,
                                         c="b",
                                         label="ECG")

        self.second_line, = self.ax.plot(
            range(
                self.composite_peaks.ST_start.data[self.index],
                int(
                    np.median([
                        self.composite_peaks.T.data[self.index],
                        len(self.signal)
                    ]))),
            2 + 15 * self.second[range(
                self.composite_peaks.ST_start.data[self.index],
                int(
                    np.median([
                        self.composite_peaks.T.data[self.index],
                        len(self.signal)
                    ])))],
            '--',
            linewidth=0.5,
            c='k',
            label="ECG 2nd Derv.")

        self.seis_line, = self.ax.plot(self.seis,
                                       '--',
                                       linewidth=0.5,
                                       c='r',
                                       label="Seis")
        self.phono_line, = self.ax.plot(self.phono,
                                        '--',
                                        linewidth=0.5,
                                        c='g',
                                        label="Phono")

        self.ax.set_xlim(0, len(self.signal))

        sig_min = min(self.signal)
        sig_max = max(self.signal)

        self.ax.set_ylim(sig_min - 0.1 * (sig_max - sig_min),
                         sig_max + 0.1 * (sig_max - sig_min))
        plt.legend(loc='upper right')

        # Q Peak
        self.q_point = self.ax.scatter(
            self.composite_peaks.Q.data[self.index],
            self.signal[self.composite_peaks.Q.data[self.index]],
            c='#ff7f0e')
        self.q_text = self.ax.text(
            self.composite_peaks.Q.data[self.index],
            self.signal[self.composite_peaks.Q.data[self.index]] + 0.2,
            "Q",
            fontsize=9,
            horizontalalignment='center')

        # QM Seismo
        self.qm_seis_point = self.ax.scatter(
            self.composite_peaks.QM_seis.data[self.index],
            self.seis[self.composite_peaks.QM_seis.data[self.index]],
            c='#d62728')
        self.qm_seis_text = self.ax.text(
            self.composite_peaks.QM_seis.data[self.index],
            self.seis[self.composite_peaks.QM_seis.data[self.index]] + 0.2,
            "QM Seis",
            fontsize=9,
            horizontalalignment='center')

        # QM Phono
        self.qm_phono_point = self.ax.scatter(
            self.composite_peaks.QM_phono.data[self.index],
            self.phono[self.composite_peaks.QM_phono.data[self.index]],
            c='#8c564b')
        self.qm_phono_text = self.ax.text(
            self.composite_peaks.QM_phono.data[self.index],
            self.phono[self.composite_peaks.QM_phono.data[self.index]] + 0.2,
            "QM Phono",
            fontsize=9,
            horizontalalignment='center')

        # T''max Peak
        self.ddT_max_point = self.ax.scatter(
            self.composite_peaks.ddT_max.data[self.index],
            self.signal[self.composite_peaks.ddT_max.data[self.index]],
            c='#2ca02c')
        self.ddT_max_text = self.ax.text(
            self.composite_peaks.ddT_max.data[self.index],
            self.signal[self.composite_peaks.ddT_max.data[self.index]] + 0.2,
            "T''max",
            fontsize=9,
            horizontalalignment='center')

        # TM Seismo
        self.tm_seis_point = self.ax.scatter(
            self.composite_peaks.TM_seis.data[self.index],
            self.seis[self.composite_peaks.TM_seis.data[self.index]],
            c='#9467bd')
        self.tm_seis_text = self.ax.text(
            self.composite_peaks.TM_seis.data[self.index],
            self.seis[self.composite_peaks.TM_seis.data[self.index]] + 0.2,
            "TM Seis",
            fontsize=9,
            horizontalalignment='center')

        # TM Phono
        self.tm_phono_point = self.ax.scatter(
            self.composite_peaks.TM_phono.data[self.index],
            self.phono[self.composite_peaks.TM_phono.data[self.index]],
            c='#e377c2')
        self.tm_phono_text = self.ax.text(
            self.composite_peaks.TM_phono.data[self.index],
            self.phono[self.composite_peaks.TM_phono.data[self.index]] + 0.2,
            "TM Phono",
            fontsize=9,
            horizontalalignment='center')

        # Initalize axes and data points
        self.x = range(len(self.signal))
        self.y = self.signal

        # Cross hairs
        self.lx = self.ax.axhline(color='k', linewidth=0.2)  # the horiz line
        self.ly = self.ax.axvline(color='k', linewidth=0.2)  # the vert line

        # Add data
        left_shift = 0.45
        start = 0.96
        space = 0.04
        self.ax.text(0.01,
                     start,
                     transform=self.ax.transAxes,
                     s="Folder: " + self.folder_name,
                     fontsize=12,
                     horizontalalignment='left')
        self.ax.text(0.01,
                     start - space,
                     transform=self.ax.transAxes,
                     s="Dosage: " + str(self.dosage),
                     fontsize=12,
                     horizontalalignment='left')
        self.ax.text(0.01,
                     start - 2 * space,
                     transform=self.ax.transAxes,
                     s="File: " + self.file_name,
                     fontsize=12,
                     horizontalalignment='left')
        self.ax.text(0.01,
                     start - 3 * space,
                     transform=self.ax.transAxes,
                     s="File #: " + str(self.interval_number),
                     fontsize=12,
                     horizontalalignment='left')
        self.i_text = self.ax.text(0.60 - left_shift,
                                   1.1 - space,
                                   transform=self.ax.transAxes,
                                   s="Composite: " + str(self.index + 1) +
                                   "/" +
                                   str(len(self.composite_peaks.composites)),
                                   fontsize=12,
                                   horizontalalignment='left')

        # Add Intervals
        start_left = 0.575
        shift_left = 0.10
        qm_seis = str(
            round(
                1 / (self.time[self.composite_peaks.QM_seis.data[self.index]] -
                     self.time[self.composite_peaks.Q.data[self.index]]), 2))
        qm_phono = str(
            round(
                1 /
                (self.time[self.composite_peaks.QM_phono.data[self.index]] -
                 self.time[self.composite_peaks.Q.data[self.index]]), 2))
        self.qm_text = self.ax.text(start_left,
                                    0.91,
                                    horizontalalignment='center',
                                    transform=self.fig.transFigure,
                                    s="1/(E-M)ino\nSeis: " + qm_seis + " Hz" +
                                    "\nPhono: " + qm_phono + " Hz")
        tm_seis = str(
            round(
                1 / (self.time[self.composite_peaks.TM_seis.data[self.index]] -
                     self.time[self.composite_peaks.ddT_max.data[self.index]]),
                2))
        tm_phono = str(
            round(
                1 /
                (self.time[self.composite_peaks.TM_phono.data[self.index]] -
                 self.time[self.composite_peaks.ddT_max.data[self.index]]), 2))
        self.tm_text = self.ax.text(start_left + shift_left,
                                    0.91,
                                    horizontalalignment='center',
                                    transform=self.fig.transFigure,
                                    s="1/(E-M)lusi\nSeis: " + tm_seis + " Hz" +
                                    "\nPhono: " + tm_phono + " Hz")

        # Add index buttons
        ax_prev = plt.axes([0.575 - left_shift, 0.9, 0.1, 0.075])
        self.bprev = Button(ax_prev, 'Previous')
        self.bprev.on_clicked(self.prev)

        ax_next = plt.axes([0.8 - left_shift, 0.9, 0.1, 0.075])
        self.b_next = Button(ax_next, 'Next')
        self.b_next.on_clicked(self.next)

        self.fig.canvas.mpl_connect('motion_notify_event', self.mouse_move)

        # Add Save Button
        ax_save = plt.axes([0.8, 0.9, 0.1, 0.075])
        self.b_save = Button(ax_save, 'Save')
        self.b_save.on_clicked(self.save)

        # Add Line buttons
        self.ax.text(-0.13,
                     0.97,
                     transform=self.ax.transAxes,
                     s="Snap on to:",
                     fontsize=12,
                     horizontalalignment='left')
        # left, bottom, width, height
        ax_switch_signals = plt.axes([0.02, 0.7, 0.07, 0.15])
        self.b_switch_signals = RadioButtons(ax_switch_signals,
                                             ('ECG', 'Seismo', 'Phono'))
        for c in self.b_switch_signals.circles:
            c.set_radius(0.05)

        self.b_switch_signals.on_clicked(self.switch_signal)

        self.fig.canvas.mpl_connect('button_press_event', self.on_click)
        self.fig.canvas.mpl_connect('button_release_event', self.off_click)

        # Add Line hide buttons
        self.ax.text(1.015,
                     0.97,
                     transform=self.ax.transAxes,
                     s="Hide Signal:",
                     fontsize=12,
                     horizontalalignment='left')
        ax_hide_signals = plt.axes([0.91, 0.7, 0.07, 0.15])
        self.b_hide_signals = CheckButtons(ax_hide_signals,
                                           ('ECG', 'Seismo', 'Phono'))

        self.b_hide_signals.on_clicked(self.switch_signal)

        # Add Sliders
        self.signal_amp_slider = Slider(plt.axes([0.91, 0.15, 0.01, 0.475]),
                                        label="ECG\nA",
                                        valmin=0.01,
                                        valmax=10,
                                        valinit=1,
                                        orientation='vertical')
        self.signal_amp_slider.on_changed(self.switch_signal)
        self.signal_amp_slider.valtext.set_visible(False)

        self.seis_height_slider = Slider(plt.axes([0.93, 0.15, 0.01, 0.475]),
                                         label="   Seis\nH",
                                         valmin=1.5 * min(self.signal),
                                         valmax=1.5 * max(self.signal),
                                         valinit=0,
                                         orientation='vertical')
        self.seis_height_slider.on_changed(self.switch_signal)
        self.seis_height_slider.valtext.set_visible(False)

        self.seis_amp_slider = Slider(plt.axes([0.94, 0.15, 0.01, 0.475]),
                                      label="\nA",
                                      valmin=0.01,
                                      valmax=10,
                                      valinit=1,
                                      orientation='vertical')
        self.seis_amp_slider.on_changed(self.switch_signal)
        self.seis_amp_slider.valtext.set_visible(False)

        self.phono_height_slider = Slider(plt.axes([0.96, 0.15, 0.01, 0.475]),
                                          label="    Phono\nH",
                                          valmin=1.5 * min(self.signal),
                                          valmax=1.5 * max(self.signal),
                                          valinit=0,
                                          orientation='vertical')
        self.phono_height_slider.on_changed(self.switch_signal)
        self.phono_height_slider.valtext.set_visible(False)

        self.phono_amp_slider = Slider(plt.axes([0.97, 0.15, 0.01, 0.475]),
                                       label="A",
                                       valmin=.01,
                                       valmax=10,
                                       valinit=1,
                                       orientation='vertical')
        self.phono_amp_slider.on_changed(self.switch_signal)
        self.phono_amp_slider.valtext.set_visible(False)

        # Maximize frame
        mng = plt.get_current_fig_manager()
        mng.full_screen_toggle()

        plt.show()
예제 #6
0
        # Bandblock
        if show_bandpass == True:
            bandpass_signal = hb.lowpass_filter(time=time,
                                                signal=signal,
                                                cutoff_freq=10)

            hb.get_fft(time=time, signal=bandpass_signal, plot=True)

        # View Derivatives
        if show_derivatives == True:
            bandpass_signal = hb.bandpass_filter(time=time,
                                                 signal=signal,
                                                 freqmin=59,
                                                 freqmax=61)
            hb.get_derivatives(signal=bandpass_signal, plot=True)

        # Find Peaks
        if show_peaks:

            # Bandpass out 60 Hz
            filtered_signal = hb.bandpass_filter(time=time,
                                                 signal=signal,
                                                 freqmin=59,
                                                 freqmax=61)

            filtered_seis2 = hb.bandpass_filter(time=time,
                                                signal=seis2,
                                                freqmin=59,
                                                freqmax=61)
예제 #7
0
    def plot_signals(self):
        # Create figure
        self.fig, self.ax = plt.subplots()
        self.signal = hb.normalize(self.peaks.signal[range(self.peaks.P.data[self.index], self.peaks.T.data[self.index + 1])])

        # Determine what cutoff freq to use
        self.cutoff_freq = 15 if np.mean(np.diff(self.peaks.R.data)) > 2500 else 10

        # Pass through a Low pass
        self.smoothed_signal = hb.lowpass_filter(signal = self.signal,
                                            cutoff_freq = self.cutoff_freq)

        # Calculate first derivative
        self.first, _ = hb.get_derivatives(self.smoothed_signal)

        # Plot ECG, Phono and Seismo
        self.signal_line, = self.ax.plot(range(len(self.signal)), self.signal, linewidth = 0.75, c = "r", label = "ECG")

        self.smooth_signal_line, = self.ax.plot(range(len(self.signal)), self.smoothed_signal, linewidth = 1, c = "b", label = "Low Pass ECG")

        self.first_line, = self.ax.plot(range(len(self.signal)), 1 + 5*self.first,
                                        '--', linewidth = 0.5, c = 'k', label = "ECG 1st Derv.")

        self.ax.set_xlim(0, len(self.signal))

        sig_min = min(self.signal)
        sig_max = max(self.signal)

        self.ax.set_ylim(sig_min - 0.2*(sig_max - sig_min), sig_max + 0.2*(sig_max - sig_min))
        plt.legend(loc='upper right')

        # T Peak
        self.T_point = self.ax.scatter(self.peaks.T.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.T.data[self.index] - self.peaks.P.data[self.index]], c = '#9467bd')
        self.T_text  = self.ax.text(self.peaks.T.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.T.data[self.index] - self.peaks.P.data[self.index]] + 0.2, "T", fontsize=9, horizontalalignment = 'center')

         # ST Start Peak
        self.ST_start_point = self.ax.scatter(self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index]], c = 'y')
        self.ST_start_text  = self.ax.text(self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index]] + 0.2, "ST Start", fontsize=9, horizontalalignment = 'center')

        # T'max Peak
        self.dT_point = self.ax.scatter(self.peaks.dT.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.dT.data[self.index] - self.peaks.P.data[self.index]], c = '#2ca02c')
        self.dT_text  = self.ax.text(self.peaks.dT.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.dT.data[self.index] - self.peaks.P.data[self.index]] + 0.2, "T'max", fontsize=9, horizontalalignment = 'center')

        # # T''max Peak
        # self.ddT_point = self.ax.scatter(self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index]], c = '#2ca02c')
        # self.ddT_text  = self.ax.text(self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index]] + 0.2, "T''max", fontsize=9, horizontalalignment = 'center')

        # Initalize axes and data points
        self.x = range(len(self.signal))
        self.y = self.smoothed_signal

        # Cross hairs
        self.lx = self.ax.axhline(color='k', linewidth=0.2)  # the horiz line
        self.ly = self.ax.axvline(color='k', linewidth=0.2)  # the vert line

        # Add data
        left_shift = 0.45
        start = 0.96
        space = 0.04
        self.ax.text(0.01, start, transform = self.ax.transAxes,
                    s = "Folder: " + self.folder_name, fontsize=12, horizontalalignment = 'left')
        self.ax.text(0.01, start - space, transform = self.ax.transAxes,
                    s = "Dosage: " + str(self.dosage), fontsize=12, horizontalalignment = 'left')
        self.i_text = self.ax.text(0.60 - left_shift, 1.1 - space, transform = self.ax.transAxes,
                                    s = "Heartbeat: " + str(self.index + 1) + "/" + str(len(self.peaks.R.data) - 1), fontsize=12, horizontalalignment = 'left')

        # Add index buttons
        ax_prev = plt.axes([0.575 - left_shift, 0.9, 0.1, 0.075])
        self.bprev = Button(ax_prev, 'Previous')
        self.bprev.on_clicked(self.prev)
        
        ax_next = plt.axes([0.8 - left_shift, 0.9, 0.1, 0.075])
        self.b_next = Button(ax_next, 'Next')
        self.b_next.on_clicked(self.next)

        self.fig.canvas.mpl_connect('motion_notify_event', self.mouse_move)

        self.fig.canvas.mpl_connect('button_press_event', self.on_click)
        self.fig.canvas.mpl_connect('button_release_event', self.off_click)

        # Add Sliders
        start = 0.91
        slider_width = 0.0075
        slider_height = 0.47

        self.cutoff_amp_slider = Slider(plt.axes([0.05, 0.15, 2*slider_width, slider_height]),
                                                label = "Cutoff (Hz)",
                                                valmin = 1,
                                                valmax = 50, 
                                                valinit = self.cutoff_freq,
                                                orientation = 'vertical',
                                                valfmt='%0.0f')
        self.cutoff_amp_slider.label.set_size(8)
        self.cutoff_amp_slider.on_changed(self.switch_signal)

        self.signal_amp_slider = Slider(plt.axes([start, 0.15, slider_width, slider_height]),
                                                label = "ECG\n\nA",
                                                valmin = 0.01,
                                                valmax = 10, 
                                                valinit = 1,
                                                orientation = 'vertical')
        self.signal_amp_slider.label.set_size(8)
        self.signal_amp_slider.on_changed(self.switch_signal)
        self.signal_amp_slider.valtext.set_visible(False)

        self.first_height_slider = Slider(plt.axes([start + 2*slider_width, 0.15, slider_width, slider_height]),
                                                    label = "   1st\n    Derv.\nH",
                                                    valmin = 1.5 * min(self.signal),
                                                    valmax = 1.5 * max(self.signal), 
                                                    valinit = 0,
                                                    orientation = 'vertical')
        self.first_height_slider.label.set_size(8)
        self.first_height_slider.on_changed(self.switch_signal)
        self.first_height_slider.valtext.set_visible(False)

        self.first_amp_slider = Slider(plt.axes([start + 3*slider_width, 0.15, slider_width, slider_height]),
                                        label = "\nA",
                                        valmin = 0.01,
                                        valmax = 10, 
                                        valinit = 1,
                                        orientation = 'vertical')
        self.first_amp_slider.label.set_size(8)
        self.first_amp_slider.on_changed(self.switch_signal)
        self.first_amp_slider.valtext.set_visible(False)

        # Maximize frame
        mng = plt.get_current_fig_manager()
        mng.full_screen_toggle()

        plt.show()