def __init__(self, parent, trace, fig_nrows=1, fig_ncols=1, ax_pos=1): super(TracePlot, self).__init__() self.parent = parent self.fig = parent.fig self.ax = self.fig.add_subplot(fig_nrows, fig_ncols, ax_pos, visible=False) self.trace = trace # Get trace dataseries self.signal = trace.signal self.time = np.linspace(0, len(self.signal) / trace.fs, num=len(self.signal), endpoint=False) self.xmin, self.xmax = 0, self.time[-1] # Plot current data self._plot_data = self.ax.plot(self.time, self.signal, color='black', rasterized=True)[0] self.ax.callbacks.connect('xlim_changed', self.on_xlim_change) self.ax.set_xlim(self.xmin, self.xmax) # Format axes axes_formatter = FuncFormatter(lambda x, pos: clt.float_secs_2_string_date(x, trace.starttime)) self.ax.xaxis.set_major_formatter(axes_formatter) plt.setp(self.ax.get_xticklabels(), visible=False) plt.setp(self.ax.get_yticklabels(), visible=False) self.ax.grid(True, which='both') # Set event markers self.marker_select_color = 'r' self.marker_color = 'b' self.markers = {} self.update_markers() # Selection parameters self.selected = False self.selector = self.ax.axvspan(0, self.xmax, fc='LightCoral', ec='r', alpha=0.5, visible=False)#, animated=True) # Place legend at = AnchoredText(self.trace.short_name, prop=dict(size=12), frameon=True, loc=2) at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2") self.ax.add_artist(at)
def on_position_estimated(self, time, aic, n0_aic): self.event_time = time time_in_secs = self.event_time / self.record.fs self.position_label.setText("Estimated Arrival Time: {}".format( clt.float_secs_2_string_date(time_in_secs, starttime=self.record.starttime))) # Plot estimated arrival time m_event = rc.ApasvoEvent(self.record, time, aic=aic, n0_aic=n0_aic) m_event.plot_aic(show_envelope=True, num=self.fig.number) self.fig.canvas.draw_idle()
def __init__(self, parent, trace, fig_nrows=1, fig_ncols=1, ax_pos=1): super(TracePlot, self).__init__() self.parent = parent self.fig = parent.fig self.ax = self.fig.add_subplot(fig_nrows, fig_ncols, ax_pos, visible=False) self.trace = trace # Get trace dataseries self.signal = trace.signal self.time = np.linspace(0, len(self.signal) / trace.fs, num=len(self.signal), endpoint=False) self.xmin, self.xmax = 0, self.time[-1] # Plot current data self._plot_data = self.ax.plot(self.time, self.signal, color='black', rasterized=True)[0] self.ax.callbacks.connect('xlim_changed', self.on_xlim_change) self.ax.set_xlim(self.xmin, self.xmax) # Format axes axes_formatter = FuncFormatter( lambda x, pos: clt.float_secs_2_string_date(x, trace.starttime)) self.ax.xaxis.set_major_formatter(axes_formatter) plt.setp(self.ax.get_xticklabels(), visible=False) plt.setp(self.ax.get_yticklabels(), visible=False) self.ax.grid(True, which='both') # Set event markers self.marker_select_color = 'r' self.marker_color = 'b' self.markers = {} self.update_markers() # Selection parameters self.selected = False self.selector = self.ax.axvspan(0, self.xmax, fc='LightCoral', ec='r', alpha=0.5, visible=False) #, animated=True) # Place legend at = AnchoredText(self.trace.short_name, prop=dict(size=12), frameon=True, loc=2) at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2") self.ax.add_artist(at)
def set_position(self, value): time_in_samples = int(value * self.event.record.fs) if time_in_samples != self.position: if 0 <= time_in_samples <= len(self.event.record.signal): self.position = time_in_samples time_in_seconds = time_in_samples / float(self.event.record.fs) for marker in self.markers: marker.set_xdata(time_in_seconds) if 0 <= self.position < len(self.event.record.cf): cf_value = self.event.record.cf[self.position] else: cf_value = np.nan self.position_label.set_text("Time: %s seconds.\nCF value: %.6g" % (clt.float_secs_2_string_date(time_in_seconds), cf_value)) self.minimap.set_marker_position(self.event, time_in_seconds)
def set_position(self, value): time_in_samples = int(value * self.event.record.fs) if time_in_samples != self.position: if 0 <= time_in_samples <= len(self.event.record.signal): self.position = time_in_samples time_in_seconds = time_in_samples / float(self.event.record.fs) for marker in self.markers: marker.set_xdata(time_in_seconds) if 0 <= self.position < len(self.event.record.cf): cf_value = self.event.record.cf[self.position] else: cf_value = np.nan self.position_label.set_text( "Time: %s seconds.\nCF value: %.6g" % (clt.float_secs_2_string_date(time_in_seconds), cf_value)) self.minimap.set_marker_position(self.event, time_in_seconds)
def plot_signal(self, t_start=0.0, t_end=np.inf, show_events=True, show_x=True, show_cf=True, show_specgram=True, show_envelope=True, threshold=None, num=None, **kwargs): """Plots record data. Draws a figure containing several plots for data stored and computed by a Record object: magnitude, envelope and spectrogram plots for self.signal, as well as characteristic function if calculated. Args: t_start: Start time of the plotted data segment, in seconds. Default: 0.0, that is the beginning of 'signal'. t_end: End time of the plotted data segment, in seconds. Default: numpy.inf, that is the end of 'signal' show_events: Boolean value to specify whether to plot event arrival times or not. Arrival times will be indicated by using a vertical line. Default: True. show_x: Boolean value to specify whether to plot the magnitude value of 'signal' or not. This function will be drawn preferably on the first axis. Default: True. show_cf: Boolean value to specify whether to plot the characteristic function or not. This function will be drawn preferably on the second axis. Default: True. show_specgram: Boolean value to specify whether to plot the spectrogram of 'signal' or not. It will be drawn preferably on the third axis. Default: True. show_envelope: Boolean value to specify whether to plot the envelope of 'signal' or not. This function will be drawn preferably on the first axis together with amplitude of 'signal'. Default: True. threshold: Boolean value to specify whether to plot threshold or not. Threshold will be drawn as an horizontal dashed line together with characteristic function. Default: True. num: Identifier of the returned MatplotLib figure, integer type. Default None, which means an identifier value will be automatically generated. Returns: fig: A MatplotLib Figure instance. """ # Lazy matplotlib import import matplotlib.pyplot as pl from matplotlib import ticker # Set limits i_from = int(max(0.0, t_start * self.fs)) if show_cf: i_to = int(min(len(self.cf), t_end * self.fs)) else: i_to = int(min(len(self.signal), t_end * self.fs)) # Create time sequence t = np.arange(i_from, i_to) / float(self.fs) # Create figure nplots = show_x + show_cf + show_specgram fig, _ = pl.subplots(nplots, 1, sharex='all', num=num) fig.canvas.set_window_title(self.label) fig.set_tight_layout(True) # Configure axes for ax in fig.axes: ax.cla() ax.grid(True, which='both') formatter = ticker.FuncFormatter( lambda x, pos: clt.float_secs_2_string_date(x, self.starttime)) ax.xaxis.set_major_formatter(formatter) ax.xaxis.set_major_locator( ticker.MaxNLocator(nbins=5, prune='lower')) ax.set_xlabel('Time (seconds)') pl.setp(ax.get_xticklabels(), visible=True) # Draw axes ax_idx = 0 # Draw signal if show_x: fig.axes[ax_idx].set_title("Signal Amplitude (%gHz)" % self.fs) fig.axes[ax_idx].set_ylabel('Amplitude') fig.axes[ax_idx].plot( t, self.signal[i_from:i_to], color='black', label='Signal') # Draw signal envelope if show_envelope: fig.axes[ax_idx].plot( t, env.envelope(self.signal[i_from:i_to]), color='r', label='Envelope') fig.axes[ax_idx].legend(loc=0, fontsize='small') ax_idx += 1 # Draw Characteristic function if show_cf: fig.axes[ax_idx].set_title('Characteristic Function') fig.axes[ax_idx].plot(t, self.cf[i_from:i_to]) # Draw threshold if threshold: hline = fig.axes[ax_idx].axhline(threshold, label="Threshold") hline.set(color='b', ls='--', lw=2, alpha=0.8) fig.axes[ax_idx].legend(loc=0, fontsize='small') ax_idx += 1 # Draw spectrogram if show_specgram: fig.axes[ax_idx].set_title('Spectrogram') fig.axes[ax_idx].set_ylabel('Frequency (Hz)') fig.axes[ax_idx].specgram( self.signal[i_from:i_to], Fs=self.fs, xextent=(i_from / self.fs, i_to / self.fs)) ax_idx += 1 # Draw event markers if show_events: for event in self.events: arrival_time = event.stime / self.fs for ax in fig.axes: xmin, xmax = ax.get_xlim() if arrival_time > xmin and arrival_time < xmax: vline = ax.axvline(arrival_time, label="Event") vline.set(color='r', ls='--', lw=2) ax.legend(loc=0, fontsize='small') # Configure limits and draw legend for ax in fig.axes: ax.set_xlim(t[0], t[-1]) return fig
def plot_aic(self, show_envelope=True, num=None, **kwargs): """Plots AIC values for a given event object. Draws a figure with two axes: the first one plots magnitude and envelope of 'self.signal' and the second one plots AIC values computed after applying Takanami AR method to 'event'. Plotted data goes from 'event.n0_aic' to 'event.n0_aic + len(event.aic)'. Args: show_envelope: Boolean value to specify whether to plot the envelope of 'signal' or not. This function will be drawn preferably on the first axis together with amplitude of 'signal'. Default: True. num: Identifier of the returned MatplotLib figure, integer type. Default None, which means an identifier value will be automatically generated. Returns: fig: A MatplotLib Figure instance. """ if self.aic is None or self.n0_aic is None: raise ValueError("Event doesn't have AIC data to plot") # Lazy matplotlib import import matplotlib.pyplot as pl from matplotlib import ticker # Set limits i_from = int(max(0, self.n0_aic)) i_to = int(min(len(self.trace.signal), self.n0_aic + len(self.aic))) # Create time sequence t = np.arange(i_from, i_to) / float(self.trace.fs) # Create figure fig, _ = pl.subplots(2, 1, sharex='all', num=num) fig.canvas.set_window_title(self.trace.label) fig.set_tight_layout(True) # Configure axes for ax in fig.axes: ax.cla() ax.grid(True, which='both') formatter = ticker.FuncFormatter(lambda x, pos: clt.float_secs_2_string_date(x, self.trace.starttime)) ax.xaxis.set_major_formatter(formatter) ax.xaxis.set_major_locator( ticker.MaxNLocator(nbins=5, prune='lower')) ax.set_xlabel('Time (seconds)') pl.setp(ax.get_xticklabels(), visible=True) # Draw signal fig.axes[0].set_title('Signal Amplitude') fig.axes[0].set_ylabel('Amplitude') fig.axes[0].plot( t, self.trace.signal[i_from:i_to], color='black', label='Signal') # Draw envelope if show_envelope: fig.axes[0].plot( t, env.envelope(self.trace.signal[i_from:i_to]), color='r', label='Envelope') fig.axes[0].legend(loc=0, fontsize='small') # Draw AIC fig.axes[1].set_title('AIC') fig.axes[1].plot(t, self.aic) # Draw event for ax in fig.axes: vline = ax.axvline(self.stime / self.trace.fs, label="Event") vline.set(color='r', ls='--', lw=2) # Configure limits and draw legend for ax in fig.axes: ax.set_xlim(t[0], t[-1]) ax.legend(loc=0, fontsize='small') return fig
def __init__(self, parent, document=None): super(SignalViewerWidget, self).__init__(parent) self.document = document self.xmin = 0.0 self.xmax = 0.0 self.xleft = 0.0 self.xright = 0.0 self.time = np.array([]) self.fs = 0.0 self.signal = None self.envelope = None self.cf = None self.time = None self._signal_data = None self._envelope_data = None self._cf_data = None self.fig, _ = plt.subplots(3, 1) self.signal_ax = self.fig.axes[0] self.cf_ax = self.fig.axes[1] self.specgram_ax = self.fig.axes[2] self.canvas = FigureCanvas(self.fig) self.canvas.setSizePolicy( QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Expanding, QtGui.QSizePolicy.Policy.Expanding)) self.canvas.setMinimumHeight(320) self.graphArea = QtGui.QScrollArea(self) self.graphArea.setWidget(self.canvas) self.graphArea.setWidgetResizable(True) self.eventMarkers = {} self.last_right_clicked_event = None self.thresholdMarker = None self.playback_marker = None self.selector = SpanSelector(self.fig) self.minimap = MiniMap(self, self.signal_ax, None) # Load Spectrogram settings self.update_specgram_settings() # Animation related attributes self.background = None self.animated = False # Create context menus self.event_context_menu = QtGui.QMenu(self) self.takanami_on_event_action = QtGui.QAction( "Apply Takanami to Event", self) self.takanami_on_event_action.setStatusTip( "Refine event position by using Takanami algorithm") self.event_context_menu.addAction(self.takanami_on_event_action) self.takanami_on_event_action.triggered.connect( self.apply_takanami_to_selected_event) self.selection_context_menu = QtGui.QMenu(self) self.create_event_action = QtGui.QAction( "Create New Event on Selection", self) self.create_event_action.setStatusTip( "Create a new event on selection") self.takanami_on_selection_action = QtGui.QAction( "Apply Takanami to Selection", self) self.takanami_on_selection_action.setStatusTip( "Apply Takanami algorithm to selection") self.selection_context_menu.addAction(self.create_event_action) self.selection_context_menu.addAction( self.takanami_on_selection_action) self.create_event_action.triggered.connect( self.create_event_on_selection) self.takanami_on_selection_action.triggered.connect( self.apply_takanami_to_selection) # format axes formatter = FuncFormatter(lambda x, pos: clt.float_secs_2_string_date( x, self.document.record.starttime)) for ax in self.fig.axes: ax.callbacks.connect('xlim_changed', self.on_xlim_change) ax.xaxis.set_major_formatter(formatter) plt.setp(ax.get_xticklabels(), visible=True) ax.grid(True, which='both') self.specgram_ax.callbacks.connect('ylim_changed', self.on_ylim_change) self.specgram_ax.set_xlabel('Time (seconds)') plt.setp(self.signal_ax.get_yticklabels(), visible=False) #self.signal_ax.set_ylabel('Signal Amp.') self.cf_ax.set_ylabel('CF Amp.') self.specgram_ax.set_ylabel('Frequency (Hz)') # Set the layout self.layout = QtGui.QVBoxLayout(self) self.layout.addWidget(self.graphArea) self.layout.addWidget(self.minimap) self.selector.toggled.connect(self.minimap.set_selection_visible) self.selector.valueChanged.connect(self.minimap.set_selection_limits) self.selector.right_clicked.connect(self.on_selector_right_clicked) if self.document is not None: self.set_record(document)
def plot_signal(self, t_start=0.0, t_end=np.inf, show_events=True, show_x=True, show_cf=True, show_specgram=True, show_envelope=True, threshold=None, num=None, **kwargs): """Plots record data. Draws a figure containing several plots for data stored and computed by a Record object: magnitude, envelope and spectrogram plots for self.signal, as well as characteristic function if calculated. Args: t_start: Start time of the plotted data segment, in seconds. Default: 0.0, that is the beginning of 'signal'. t_end: End time of the plotted data segment, in seconds. Default: numpy.inf, that is the end of 'signal' show_events: Boolean value to specify whether to plot event arrival times or not. Arrival times will be indicated by using a vertical line. Default: True. show_x: Boolean value to specify whether to plot the magnitude value of 'signal' or not. This function will be drawn preferably on the first axis. Default: True. show_cf: Boolean value to specify whether to plot the characteristic function or not. This function will be drawn preferably on the second axis. Default: True. show_specgram: Boolean value to specify whether to plot the spectrogram of 'signal' or not. It will be drawn preferably on the third axis. Default: True. show_envelope: Boolean value to specify whether to plot the envelope of 'signal' or not. This function will be drawn preferably on the first axis together with amplitude of 'signal'. Default: True. threshold: Boolean value to specify whether to plot threshold or not. Threshold will be drawn as an horizontal dashed line together with characteristic function. Default: True. num: Identifier of the returned MatplotLib figure, integer type. Default None, which means an identifier value will be automatically generated. Returns: fig: A MatplotLib Figure instance. """ # Lazy matplotlib import import matplotlib.pyplot as pl from matplotlib import ticker # Set limits i_from = int(max(0.0, t_start * self.fs)) if show_cf: i_to = int(min(len(self.cf), t_end * self.fs)) else: i_to = int(min(len(self.signal), t_end * self.fs)) # Create time sequence t = np.arange(i_from, i_to) / float(self.fs) # Create figure nplots = show_x + show_cf + show_specgram fig, _ = pl.subplots(nplots, 1, sharex='all', num=num) fig.canvas.set_window_title(self.label) fig.set_tight_layout(True) # Configure axes for ax in fig.axes: ax.cla() ax.grid(True, which='both') formatter = ticker.FuncFormatter(lambda x, pos: clt.float_secs_2_string_date(x, self.starttime)) ax.xaxis.set_major_formatter(formatter) ax.xaxis.set_major_locator(ticker.MaxNLocator(nbins=5, prune='lower')) ax.set_xlabel('Time (seconds)') pl.setp(ax.get_xticklabels(), visible=True) # Draw axes ax_idx = 0 # Draw signal if show_x: fig.axes[ax_idx].set_title("Signal Amplitude (%gHz)" % self.fs) fig.axes[ax_idx].set_ylabel('Amplitude') fig.axes[ax_idx].plot(t, self.signal[i_from:i_to], color='black', label='Signal') #fig.axes[ax_idx].plot(t, signal_norm, color='black', #label='Signal') # Draw signal envelope if show_envelope: fig.axes[ax_idx].plot(t, env.envelope(self.signal[i_from:i_to]), color='r', label='Envelope') fig.axes[ax_idx].legend(loc=0, fontsize='small') ax_idx += 1 # Draw Characteristic function if show_cf: fig.axes[ax_idx].set_title('Characteristic Function') fig.axes[ax_idx].plot(t, self.cf[i_from:i_to]) # Draw threshold if threshold: hline = fig.axes[ax_idx].axhline(threshold, label="Threshold") hline.set(color='b', ls='--', lw=2, alpha=0.8) fig.axes[ax_idx].legend(loc=0, fontsize='small') ax_idx += 1 # Draw spectrogram if show_specgram: fig.axes[ax_idx].set_title('Spectrogram') fig.axes[ax_idx].set_ylabel('Frequency (Hz)') fig.axes[ax_idx].specgram(self.signal[i_from:i_to], Fs=self.fs, xextent=(i_from / self.fs, i_to / self.fs)) ax_idx += 1 # Draw event markers if show_events: for event in self.events: arrival_time = event.stime / self.fs for ax in fig.axes: xmin, xmax = ax.get_xlim() if arrival_time > xmin and arrival_time < xmax: vline = ax.axvline(arrival_time, label="Event") vline.set(color='r', ls='--', lw=2) ax.legend(loc=0, fontsize='small') # Configure limits and draw legend for ax in fig.axes: ax.set_xlim(t[0], t[-1]) return fig
def plot_aic(self, show_envelope=True, num=None, **kwargs): """Plots AIC values for a given event object. Draws a figure with two axes: the first one plots magnitude and envelope of 'self.signal' and the second one plots AIC values computed after applying Takanami AR method to 'event'. Plotted data goes from 'event.n0_aic' to 'event.n0_aic + len(event.aic)'. Args: show_envelope: Boolean value to specify whether to plot the envelope of 'signal' or not. This function will be drawn preferably on the first axis together with amplitude of 'signal'. Default: True. num: Identifier of the returned MatplotLib figure, integer type. Default None, which means an identifier value will be automatically generated. Returns: fig: A MatplotLib Figure instance. """ if self.aic is None or self.n0_aic is None: raise ValueError("Event doesn't have AIC data to plot") # Lazy matplotlib import import matplotlib.pyplot as pl from matplotlib import ticker # Set limits i_from = int(max(0, self.n0_aic)) i_to = int(min(len(self.trace.signal), self.n0_aic + len(self.aic))) # Create time sequence t = np.arange(i_from, i_to) / float(self.trace.fs) # Create figure fig, _ = pl.subplots(2, 1, sharex='all', num=num) fig.canvas.set_window_title(self.trace.label) fig.set_tight_layout(True) # Configure axes for ax in fig.axes: ax.cla() ax.grid(True, which='both') formatter = ticker.FuncFormatter(lambda x, pos: clt.float_secs_2_string_date(x, self.trace.starttime)) ax.xaxis.set_major_formatter(formatter) ax.xaxis.set_major_locator(ticker.MaxNLocator(nbins=5, prune='lower')) ax.set_xlabel('Time (seconds)') pl.setp(ax.get_xticklabels(), visible=True) # Draw signal fig.axes[0].set_title('Signal Amplitude') fig.axes[0].set_ylabel('Amplitude') fig.axes[0].plot(t, self.trace.signal[i_from:i_to], color='black', label='Signal') # Draw envelope if show_envelope: fig.axes[0].plot(t, env.envelope(self.trace.signal[i_from:i_to]), color='r', label='Envelope') fig.axes[0].legend(loc=0, fontsize='small') # Draw AIC fig.axes[1].set_title('AIC') fig.axes[1].plot(t, self.aic) # Draw event for ax in fig.axes: vline = ax.axvline(self.stime / self.trace.fs, label="Event") vline.set(color='r', ls='--', lw=2) # Configure limits and draw legend for ax in fig.axes: ax.set_xlim(t[0], t[-1]) ax.legend(loc=0, fontsize='small') return fig
def __init__(self, parent, document=None): super(SignalViewerWidget, self).__init__(parent) self.document = document self.xmin = 0.0 self.xmax = 0.0 self.xleft = 0.0 self.xright = 0.0 self.time = np.array([]) self.fs = 0.0 self.signal = None self.envelope = None self.cf = None self.time = None self._signal_data = None self._envelope_data = None self._cf_data = None self.fig, _ = plt.subplots(3, 1) self.signal_ax = self.fig.axes[0] self.cf_ax = self.fig.axes[1] self.specgram_ax = self.fig.axes[2] self.canvas = FigureCanvas(self.fig) self.canvas.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Expanding, QtGui.QSizePolicy.Policy.Expanding)) self.canvas.setMinimumHeight(320) self.graphArea = QtGui.QScrollArea(self) self.graphArea.setWidget(self.canvas) self.graphArea.setWidgetResizable(True) self.eventMarkers = {} self.last_right_clicked_event = None self.thresholdMarker = None self.playback_marker = None self.selector = SpanSelector(self.fig) self.minimap = MiniMap(self, self.signal_ax, None) # Load Spectrogram settings self.update_specgram_settings() # Animation related attributes self.background = None self.animated = False # Create context menus self.event_context_menu = QtGui.QMenu(self) self.takanami_on_event_action = QtGui.QAction("Apply Takanami to Event", self) self.takanami_on_event_action.setStatusTip("Refine event position by using Takanami algorithm") self.event_context_menu.addAction(self.takanami_on_event_action) self.takanami_on_event_action.triggered.connect(self.apply_takanami_to_selected_event) self.selection_context_menu = QtGui.QMenu(self) self.create_event_action = QtGui.QAction("Create New Event on Selection", self) self.create_event_action.setStatusTip("Create a new event on selection") self.takanami_on_selection_action = QtGui.QAction("Apply Takanami to Selection", self) self.takanami_on_selection_action.setStatusTip("Apply Takanami algorithm to selection") self.selection_context_menu.addAction(self.create_event_action) self.selection_context_menu.addAction(self.takanami_on_selection_action) self.create_event_action.triggered.connect(self.create_event_on_selection) self.takanami_on_selection_action.triggered.connect(self.apply_takanami_to_selection) # format axes formatter = FuncFormatter(lambda x, pos: clt.float_secs_2_string_date(x, self.document.record.starttime)) for ax in self.fig.axes: ax.callbacks.connect('xlim_changed', self.on_xlim_change) ax.xaxis.set_major_formatter(formatter) plt.setp(ax.get_xticklabels(), visible=True) ax.grid(True, which='both') self.specgram_ax.callbacks.connect('ylim_changed', self.on_ylim_change) self.specgram_ax.set_xlabel('Time (seconds)') plt.setp(self.signal_ax.get_yticklabels(), visible=False) #self.signal_ax.set_ylabel('Signal Amp.') self.cf_ax.set_ylabel('CF Amp.') self.specgram_ax.set_ylabel('Frequency (Hz)') # Set the layout self.layout = QtGui.QVBoxLayout(self) self.layout.addWidget(self.graphArea) self.layout.addWidget(self.minimap) self.selector.toggled.connect(self.minimap.set_selection_visible) self.selector.valueChanged.connect(self.minimap.set_selection_limits) self.selector.right_clicked.connect(self.on_selector_right_clicked) if self.document is not None: self.set_record(document)