Exemple #1
0
class double_pendulum_window(QW.QMainWindow):
    """
    The main window which houses both options and plot canvas
    """
    def __init__(self):
        super().__init__()

        # Create the main Widget and layout
        self._main = QW.QWidget()
        self.setWindowTitle('Double Pendulum Simulation')
        self.setCentralWidget(self._main)
        self.layout_main = QW.QHBoxLayout(self._main)
        # A shortcut to close the app.
        self.closer = QW.QShortcut(QG.QKeySequence('Ctrl+Q'), self, self.quit)

        self.create_options()
        self.create_plot_window()

    def create_options(self):
        # Create all the options. Both the necessary backend and frontend

        # Backend - here are all the parameters
        # Since QSlider only works for integers, we create a linspace vector
        # for each parameter and use the QSlider value as the index for the
        # linspace vector.
        self.param_names = ['r1', 'm1', 'm2', 'g']
        self.param_min = [0.05, 0.1, 0.1, 1]
        self.param_max = [0.95, 10, 10, 100]
        self.param_start = [45, 9, 9, 18]
        self.param_intervals = [0.01, 0.1, 0.1, 0.5]
        self.param_values = []
        self.current_values = []
        self.param_nums = [
            ((max_ - min_) / int_ + 1) for min_, max_, int_ in zip(
                self.param_min, self.param_max, self.param_intervals)
        ]
        self.param_nums = [np.round(i).astype(int) for i in self.param_nums]

        for min_, max_, nums, start in zip(self.param_min, self.param_max,
                                           self.param_nums, self.param_start):
            # Here we create the actual linspace vectors and add them to the
            # backend
            values = np.linspace(min_, max_, nums)
            self.param_values.append(values)
            self.current_values.append(values[start])

        # Frontend
        self.param_labels = []
        self.param_fields = []
        self.param_value_labels = []

        self.layout_options = QW.QVBoxLayout()
        self.button_restart = QW.QPushButton('Restart program', self)
        self.button_restart.clicked.connect(self.restart_plot)

        # Create each line in the parameter layout
        for i, (name, max_, start, values) in enumerate(
                zip(self.param_names, self.param_nums, self.param_start,
                    self.param_values)):
            label = QW.QLabel(name, self)
            field = QW.QSlider(QC.Qt.Horizontal)
            field.setMinimum(0)
            field.setMaximum(max_ - 1)
            field.setValue(start)
            field.valueChanged.connect(
                lambda sv, i=i: self.update_param_value(sv, i))
            value_label = QW.QLabel(f'{values[start]:.2f}')
            self.param_labels.append(label)
            self.param_fields.append(field)
            self.param_value_labels.append(value_label)

        # Add the parameters to the layout
        self.layout_parameters = QW.QGridLayout()
        for n in range(len(self.param_fields)):
            self.layout_parameters.addWidget(self.param_labels[n], n, 0)
            self.layout_parameters.addWidget(self.param_fields[n], n, 1)
            self.layout_parameters.addWidget(self.param_value_labels[n], n, 2)

        self.layout_options.addWidget(self.button_restart)
        self.layout_options.addLayout(self.layout_parameters)
        self.layout_main.addLayout(self.layout_options)

    def create_plot_window(self):
        # Creates the actual plot window and initializes the animation
        self.fig, self.ax, self.ax2 = dp.animation_window()
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setFixedSize(600, 800)

        self.initialize_plot()
        self.tool = NavigationToolbar(self.canvas, self)
        self.addToolBar(self.tool)

        self.layout_main.addWidget(self.canvas)

    def update_param_value(self, slider_index, i):
        # updates the i'th parameter value
        new_value = self.param_values[i][slider_index]
        self.param_value_labels[i].setText(f'{new_value:.2f}')
        self.current_values[i] = new_value

    def restart_plot(self):
        # Clears the plotting window and makes way for a new animtion
        # Stop the animation
        self.canvas.close_event()

        # Delete the animation connection ID, figure and axes objects
        del self.cid
        del self.fig
        del self.ax
        del self.ax2

        # Remove and delete the toolbar
        self.removeToolBar(self.tool)
        del self.tool

        # Delete the canvas
        self.layout_main.removeWidget(self.canvas)
        self.canvas.deleteLater()
        self.canvas = None

        # Create the new window
        self.create_plot_window()

    def initialize_plot(self):
        # Initialize the animation class
        r1, m1, m2, g = self.current_values
        r2 = 1 - r1
        N = 3001
        dt = 0.01
        self.cid = self.canvas.mpl_connect(
            'button_press_event', lambda event: dp._on_mouse(event,
                                                             r1=r1,
                                                             r2=r2,
                                                             ax=self.ax,
                                                             ax2=self.ax2,
                                                             fig=self.fig,
                                                             N=N,
                                                             dt=dt,
                                                             m1=m1,
                                                             m2=m2,
                                                             g=g))

    def quit(self):
        sys.exit()
class MyWindow(QtWidgets.QMainWindow):
    
    def __init__(self, **kwargs):
        super(MyWindow, self).__init__()
        uic.loadUi('equation_visualizer_layout.ui', self) 
        def func(x, y):
            return np.cos(np.sqrt(x ** 2 + y ** 2))
        x = np.linspace(-5, 6, 40)
        y = np.linspace(-5, 6, 40)
        X, Y = np.meshgrid(x, y)
        Z = func(X, Y)
        
        self.fig = plt.figure()
        self.ax = plt.axes(projection='3d')
        self.ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='magma', edgecolor='none')
        
        self.ax.set_title('Surface Map Magma');
        self.ax.view_init(50, 35)
        
        self.plotWidget = FigureCanvas(self.fig)
        self.lay = QtWidgets.QVBoxLayout(self.content_plot) 
        print(self.content_plot)
        self.lay.setContentsMargins(0, 0, 0, 0)      
        self.lay.addWidget(self.plotWidget) 
        self.addToolBar(QtCore.Qt.BottomToolBarArea, NavigationToolbar(self.plotWidget, self))
        
        '''
        self.addToolBar(QtCore.Qt.BottomToolBarArea, NavigationToolbar(self.plotWidget, self))
        self.button = QPushButton('pushButtonNEW', self)
        self.button.move(70,540)
        self.button.clicked.connect(self.onClick)
        
        self.button2 = QPushButton('pushButtonNEW2', self)
        self.button2.move(350,540)
        self.button2.clicked.connect(self.onClick)
        
        self.button3 = QPushButton('pushButtonNEW3', self)
        self.button3.move(550,540)
        self.button3.clicked.connect(self.onClick)
        '''

    def create_wire_frame(self):
        def func(x, y):
            return np.cos(np.sqrt(x ** 2 + y ** 2))
        x = np.linspace(-5, 6, 40)
        y = np.linspace(-5, 6, 40)
        X, Y = np.meshgrid(x, y)
        Z = func(X, Y)
        
        fig = plt.figure()
        ax = plt.axes(projection='3d')
        ax.plot_wireframe(X, Y, Z, color='black')
        ax.set_title('wireframe');
        
        return fig
      
    
    @pyqtSlot()
    def onClick(self):
        self.plotWidget.deleteLater()
        self.__init__()
Exemple #3
0
class DendrogramWidget(QWidget):

	channel_type = data.Input
	image_widget = None
	group_combobox = None

	def __init__(self, parent = None):
		super(QWidget, self).__init__(parent)

		self.setLayout(QVBoxLayout())
	
		header_layout = QHBoxLayout()	
		header_layout.addWidget(QLabel("Selection group:"))
	
		self.group_combobox = QComboBox()
		self.group_combobox.addItems(data.selectionGroupNames())
		self.group_combobox.currentTextChanged.connect(self.update_dendrogram)
		header_layout.addWidget(self.group_combobox)
	
		self.layout().addLayout(header_layout)
		self.plot = QLabel("Select a group above...")
		self.layout().addWidget(self.plot)
		self.resize(600, 800)
		self.setWindowTitle("Dendrogram Example")
		self.show()

	def update_dendrogram(self):
		self.layout().removeWidget(self.plot)
		self.plot.deleteLater()

		group_name = self.group_combobox.currentText
		print("dendrogram: update_dendrogram %s"%(group_name))
		
		plt.clf()
		fig = plt.gcf()	
		fig.set_size_inches(8, 8)
		fig.set_dpi(120)

		X = np.array([])
		labels = []
		
		for channel in data.timeSeriesList(self.channel_type):
			if channel.name == "TotalBeam":
				continue

			labels += [channel.name]
			d = np.array([])
			for s in data.selectionGroup(group_name).selections():
				selection_data = channel.dataForSelection(s)		
				d = np.insert(d, 0, selection_data)

			try:
				d = d/np.max(d)
			except:
				labels.pop()
				print('Error processing channel %s'%(channel.name))
				continue

			if len(X) == 0:
				X = d
			else: 
				X = np.column_stack((X, d))

		try:
			linked = linkage(np.transpose(X), 'ward')
			dendrogram(linked, labels=labels)
		except RuntimeError as r:
			print(r)
			self.plot = QLabel('There was a problem processing the selected group.')
			self.layout().addWidget(self.plot)
			return

		fig.canvas.draw()
		self.plot = FigureCanvas(fig)
		self.plot.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
		self.layout().addWidget(self.plot)
Exemple #4
0
class DensityWidget(QWidget):

    xrange_plot = None
    yrange_plot = None

    def __init__(self, parent=None, width=5, height=4, dpi=100):
        super(QWidget, self).__init__(parent)
        self.setLayout(QVBoxLayout())

        self.header_layout = QHBoxLayout()
        self.layout().addLayout(self.header_layout)

        self.header_layout.addWidget(QLabel("Selection group"))
        self.group_combobox = QComboBox(self)
        self.header_layout.addWidget(self.group_combobox)

        self.header_layout.addWidget(QLabel("Channel"))
        self.channel_combobox = QComboBox(self)
        self.header_layout.addWidget(self.channel_combobox)

        axes_button = QToolButton(self)
        axes_button.setText("Setup axes")
        axes_button.clicked.connect(self.setup_axes)
        self.header_layout.addWidget(axes_button)

        spacer = QWidget(self)
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.header_layout.addWidget(spacer)

        save_button = QToolButton(self)
        save_button.setText("Save")
        save_button.clicked.connect(self.save_figure)
        self.header_layout.addWidget(save_button)

        self.plot = QLabel("Select a group above...")
        self.layout().addWidget(self.plot)

        self.group_combobox.addItems(data.selectionGroupNames())
        self.group_combobox.currentTextChanged.connect(
            lambda: self.update_plot())
        self.channel_combobox.addItems(data.timeSeriesNames())
        self.channel_combobox.currentTextChanged.connect(
            lambda: self.update_plot())
        self.setWindowTitle("Density Plot")

    def update_plot(self, xrange=None, yrange=None):
        self.layout().removeWidget(self.plot)
        self.plot.deleteLater()
        group_name = self.group_combobox.currentText
        channel_name = self.channel_combobox.currentText
        print("density: update_plot %s %s" % (group_name, channel_name))

        group = data.selectionGroup(group_name)
        channel = data.timeSeries(channel_name)

        x = np.empty(group.count) * np.nan
        err = np.empty(group.count) * np.nan

        for i, s in enumerate(group.selections()):
            r = data.result(s, channel)
            x[i] = r.value()
            err[i] = r.uncertaintyAs2SE()

        self.fig = plt.figure()
        self.fig.set_size_inches(8, 8)
        self.fig.set_dpi(120)
        ax = self.fig.add_subplot(111)

        kde = stats.gaussian_kde(x, bw_method=kde_bandwidth)

        ax.plot(x, np.zeros(x.shape), 'b|', ms=5)

        x_eval = np.linspace(0.8 * x.min(), 1.2 * x.max(), num=2000)
        ax.plot(x_eval, kde(x_eval), 'k-', label='kde')

        if xrange is None:
            self.xrange_plot = ax.get_xlim()
        else:
            print('xrange=%s' % (xrange))
            ax.set_xlim(xrange)

        if yrange is None:
            self.yrange_plot = ax.get_ylim()
        else:
            print('yrange=%s' % (yrange))
            ax.set_ylim(yrange)

        ax.set_xlabel(channel.name)

        self.fig.canvas.draw()
        self.plot = FigureCanvas(self.fig)
        self.plot.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.layout().addWidget(self.plot)

    def save_figure(self):
        fname = QFileDialog.getSaveFileName(
            self, "Save figure", QDir.homePath(),
            "Images (*.png, *.jpg, *.tif, *.pdf, *.svg")

        print("Trying to save to file %s" % (fname))
        if fname:
            self.fig.savefig(fname)

    def setup_axes(self):
        d = QDialog(self)
        l = QVBoxLayout()
        fl = QFormLayout()
        d.setLayout(l)

        params = {
            'X plot range': (self.xrange_plot, QLineEdit(), QLineEdit()),
            'Y plot range': (self.yrange_plot, QLineEdit(), QLineEdit())
        }

        for key in params:
            ll = QHBoxLayout()
            params[key][1].setText(params[key][0][0])
            params[key][2].setText(params[key][0][1])
            ll.addWidget(params[key][1])
            ll.addWidget(params[key][2])
            fl.addRow(key, ll)

        l.addLayout(fl)

        ok_button = QPushButton('Ok')
        cancel_button = QPushButton('Cancel')
        button_layout = QHBoxLayout()
        button_layout.addWidget(cancel_button)
        button_layout.addWidget(ok_button)
        l.addLayout(button_layout)

        ok_button.clicked.connect(lambda: d.accept())
        cancel_button.clicked.connect(lambda: d.reject())

        if (d.exec() == QDialog.Accepted):
            self.xrange_plot = (float(params['X plot range'][1].text),
                                float(params['X plot range'][2].text))
            self.yrange_plot = (float(params['Y plot range'][1].text),
                                float(params['Y plot range'][2].text))

            self.update_plot(xrange=self.xrange_plot, yrange=self.yrange_plot)
Exemple #5
0
class UPbContourWidget(QWidget):

    xrange_mask = (0, 30)
    yrange_mask = (0, 3)
    zrange_mask = (5000, math.inf)
    xrange_plot = (0, 30)
    yrange_plot = (0, 3)
    marker_sep = 100 * 10**6

    def __init__(self, parent=None, width=5, height=4, dpi=100):
        super(QWidget, self).__init__(parent)
        self.setLayout(QVBoxLayout())

        self.header_layout = QHBoxLayout()
        self.layout().addLayout(self.header_layout)
        self.header_layout.addWidget(QLabel("Selection group"))
        self.group_combobox = QComboBox(self)
        self.header_layout.addWidget(self.group_combobox)
        self.tw_checkbox = QCheckBox(self)
        self.tw_checkbox.setText("Tera-Wasserburg?")
        self.header_layout.addWidget(self.tw_checkbox)

        axes_button = QToolButton(self)
        axes_button.setText("Setup axes")
        axes_button.clicked.connect(self.setup_axes)
        self.header_layout.addWidget(axes_button)

        spacer = QWidget(self)
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.header_layout.addWidget(spacer)

        save_button = QToolButton(self)
        save_button.setText("Save")
        save_button.clicked.connect(self.save_figure)
        self.header_layout.addWidget(save_button)

        self.plot = QLabel("Select a group above...")
        self.layout().addWidget(self.plot)

        self.group_combobox.addItems(data.selectionGroupNames())
        self.group_combobox.currentTextChanged.connect(self.update_plot)
        self.tw_checkbox.toggled.connect(self.update_plot)
        self.setWindowTitle("U-Pb contour")

    def update_plot(self):
        self.layout().removeWidget(self.plot)
        self.plot.deleteLater()

        TW = self.tw_checkbox.checked
        group_name = self.group_combobox.currentText
        print("UPb_contour: update_plot %s %s" % (group_name, TW))

        channel_data = {}
        channel_names = ()

        if TW:
            channel_names = ('Final U238/Pb206', 'Final Pb207/Pb206',
                             'Zr96_CPS')
        else:
            channel_names = ('Final Pb207/U235', 'Final Pb206/U238',
                             'Zr96_CPS')

        for channel_name in channel_names:
            channel = data.timeSeries(channel_name)
            channel_data[channel_name] = np.array([])

            for s in data.selectionGroup(group_name).selections():
                selection_data = channel.dataForSelection(s)
                channel_data[channel_name] = np.insert(
                    channel_data[channel_name], 0, selection_data)

        masks = [self.xrange_mask, self.yrange_mask, self.zrange_mask]
        for i, mask in enumerate(masks):
            if mask is None:
                masks[i] = (-math.inf, math.inf)

        df = pd.DataFrame({
            'x': channel_data[channel_names[0]],
            'y': channel_data[channel_names[1]],
            'z': channel_data[channel_names[2]]
        })

        df = df.loc[(df['x'] > masks[0][0]) & (df['x'] < masks[0][1]) &
                    (df['y'] > masks[1][0]) & (df['y'] < masks[1][1]) &
                    (df['z'] > masks[2][0]) & (df['z'] < masks[2][1])]

        # Calculate concordia and markers
        t = np.array(range(1, 4001 * 10**6, 1 * 10**6))
        tmarkers = np.array(range(100 * 10**6, 4001 * 10**6, self.marker_sep))

        Xcon, Ycon = np.array([]), np.array([])
        Xmarkers, Ymarkers = np.array([]), np.array([])

        if TW:
            (Xcon, Ycon) = (1 / (np.exp(l238U * t) - 1), (1 / U85r) *
                            (np.exp(l235U * t) - 1) / (np.exp(l238U * t) - 1))
            (Xmarkers,
             Ymarkers) = (1 / (np.exp(l238U * tmarkers) - 1),
                          (1 / U85r) * (np.exp(l235U * tmarkers) - 1) /
                          (np.exp(l238U * tmarkers) - 1))
        else:
            (Xcon, Ycon) = (np.exp(l235U * t) - 1, np.exp(l238U * t) - 1)
            (Xmarkers, Ymarkers) = (np.exp(l235U * tmarkers) - 1,
                                    np.exp(l238U * tmarkers) - 1)

        # Do joint plot
        sb.set_style('ticks')
        self.jointgrid = sb.jointplot(df['x'],
                                      df['y'],
                                      kind="kde",
                                      height=8,
                                      space=0,
                                      n_levels=50,
                                      shade_lowest=False,
                                      xlim=self.xrange_plot,
                                      ylim=self.yrange_plot)
        self.jointgrid.ax_joint.plot(Xcon, Ycon, zorder=1)
        self.jointgrid.ax_joint.scatter(Xmarkers, Ymarkers, s=50, zorder=2)

        if TW:
            self.jointgrid.set_axis_labels(
                r'${^{238}\rm{U}}/{^{206}\rm{Pb}}$',
                r'${^{207}\rm{Pb}}/{^{206}\rm{Pb}}$',
                fontsize=24)
        else:
            self.jointgrid.set_axis_labels(r'${^{207}\rm{Pb}}/{^{235}\rm{U}}$',
                                           r'${^{206}\rm{Pb}}/{^{238}\rm{U}}$',
                                           fontsize=24)

        x_scale = 9 * 0.78 / (self.xrange_plot[1] - self.xrange_plot[0])
        y_scale = 7 * 0.80 / (self.yrange_plot[1] - self.yrange_plot[0])

        for i, a in enumerate(tmarkers):

            if (a == 0 or i < 2):
                continue

            rotation = np.degrees(
                np.arctan2((Ymarkers[i] - Ymarkers[i - 1]) * y_scale,
                           (Xmarkers[i] - Xmarkers[i - 1]) * x_scale))
            offset = (0, 0)
            self.jointgrid.ax_joint.annotate("%i" % (a / 1e6) + " Ma",
                                             xy=(Xmarkers[i], Ymarkers[i]),
                                             xytext=offset,
                                             textcoords='offset points',
                                             rotation=rotation - 90,
                                             ha='right',
                                             va='center',
                                             rotation_mode='anchor',
                                             fontsize=14)

        self.plot = FigureCanvas(self.jointgrid.fig)
        self.plot.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.layout().addWidget(self.plot)

    def save_figure(self):
        fname = QFileDialog.getSaveFileName(
            self, "Save figure", QDir.homePath(),
            "Images (*.png, *.jpg, *.tif, *.pdf, *.svg")

        print("Trying to save to file %s" % (fname))
        if fname:
            self.jointgrid.savefig(fname)

    def setup_axes(self):
        d = QDialog(self)
        l = QVBoxLayout()
        fl = QFormLayout()
        d.setLayout(l)

        params = {
            'X mask range': (self.xrange_mask, QLineEdit(), QLineEdit()),
            'Y mask range': (self.yrange_mask, QLineEdit(), QLineEdit()),
            'Z mask range': (self.zrange_mask, QLineEdit(), QLineEdit()),
            'X plot range': (self.xrange_plot, QLineEdit(), QLineEdit()),
            'Y plot range': (self.yrange_plot, QLineEdit(), QLineEdit())
        }

        for key in params:
            ll = QHBoxLayout()
            params[key][1].setText(params[key][0][0])
            params[key][2].setText(params[key][0][1])
            ll.addWidget(params[key][1])
            ll.addWidget(params[key][2])
            fl.addRow(key, ll)

        l.addLayout(fl)

        ok_button = QPushButton('Ok')
        cancel_button = QPushButton('Cancel')
        button_layout = QHBoxLayout()
        button_layout.addWidget(cancel_button)
        button_layout.addWidget(ok_button)
        l.addLayout(button_layout)

        ok_button.clicked.connect(lambda: d.accept())
        cancel_button.clicked.connect(lambda: d.reject())

        if (d.exec() == QDialog.Accepted):
            self.xrange_mask = (float(params['X mask range'][1].text),
                                float(params['X mask range'][2].text))
            self.yrange_mask = (float(params['Y mask range'][1].text),
                                float(params['Y mask range'][2].text))
            self.zrange_mask = (float(params['Z mask range'][1].text),
                                float(params['Z mask range'][2].text))
            self.xrange_plot = (float(params['X plot range'][1].text),
                                float(params['X plot range'][2].text))
            self.yrange_plot = (float(params['Y plot range'][1].text),
                                float(params['Y plot range'][2].text))

            self.update_plot()