def onclick(self, event): """ This function is in charge of the mouse-click behaviour. A left mouse button click is recognized, the mouse location serves as an initial condition for trajectories. """ # TODO: check if try/except is the best thing to do here! if not self.canvas.zoomMode: event1 = event.xdata is not None event2 = event.ydata is not None button = event.button == 1 if not self.myWidget.Equilibria.tgl: # event.xdata and event.ydata are initial conditions for integration # mouse click will also be recognized if clicked outside of the graph area, so filter that: if event1 and event2 and button: forward, backward = self.myWidget.trajectory_direction() if self.myWidget.mySystem.Trajectories.plot_trajectory([event.xdata, event.ydata], forward, backward): myLogger.message("New initial condition: " + str(event.xdata) + ", " + str(event.ydata)) else: pass else: # equilibrium point if event1 and event2 and button: equilibrium_point = self.myWidget.Equilibria.find_equilibrium([event.xdata, event.ydata]) if equilibrium_point is not None: # is this supposed to be here? pass # jacobian = self.myWidget.Equilibria.approx_ep_jacobian(equilibrium_point) # self.myWidget.mySystem.myPyplane.new_linearized_system(self.myWidget.mySystem, jacobian, equilibrium_point) else: myLogger.debug_message("in zoom mode")
def new_value(self, input_widget, section, variable): """ Ensures that a changed parameter in the ui is written into the configuration data. Parameter: input_widget -- the widget the value of which has been changed by the user section -- the configuration section the variable refers to variable -- the name of the parameter """ # read lineedit #QtCore.pyqtRemoveInputHook() #embed() if input_widget.metaObject().className() == "QLineEdit": new_value = str(input_widget.text()) elif input_widget.metaObject().className() == "QComboBox": new_value = str(input_widget.itemData(input_widget.currentIndex())) else: myLogger.debug_message("Unsupported widget type passed!") return # write config file myConfig.write(section, variable, new_value) myLogger.debug_message("New value for " + str(variable) + ":" + new_value)
def __init__(self, parent=None): super(PyplaneMainWindow, self).__init__() QtGui.QWidget.__init__(self, parent) self.setupUi(self) self.setWindowTitle('PyPlane %s' % __version__) myLogger.register_output(self.logField) self.myLayout1 = QtGui.QVBoxLayout(self.frame1) self.plotCanvas1 = Canvas(self.frame1) self.myLayout1.addWidget(self.plotCanvas1) self.myLayout2 = QtGui.QVBoxLayout(self.frame2) self.plotCanvas2 = Canvas(self.frame2) self.myLayout2.addWidget(self.plotCanvas2) self.myLayout3 = QtGui.QVBoxLayout(self.frame3) self.plotCanvas3 = Canvas(self.frame3) self.myLayout3.addWidget(self.plotCanvas3) self.myGraph = Graph(parent=self, plot_pp=self.plotCanvas1, plot_x=self.plotCanvas2, plot_y=self.plotCanvas3) self.fct_stack = [] self.linearization_stack = [] self.xDotLabel.setText(u"\u1E8B(x,y) = ") self.yDotLabel.setText(u"\u1E8F(x,y) = ") try: test = myConfig.read("Test", "test_var") except: test = "Could not load config file. Please check existence" myLogger.debug_message("Loading config file: " + test)
def submit(self): """ This function gets called after clicking on the submit button """ myLogger.message("New system submitted...") try: xtxt = str(self.xDotLineEdit.text()) ytxt = str(self.yDotLineEdit.text()) except UnicodeEncodeError as exc: myLogger.warn_message("UnicodeEncodeError! Please check input.") myLogger.debug_message(str(exc)) else: cond1 = str(self.xDotLineEdit.text()) != "" cond2 = str(self.yDotLineEdit.text()) != "" if cond1 and cond2: x_string = str(self.xDotLineEdit.text()) y_string = str(self.yDotLineEdit.text()) try: # Non-modal (!) Box intended for calming down the user... info_box = QtWidgets.QMessageBox(self) info_box.setAttribute(Qt.WA_DeleteOnClose) info_box.setStandardButtons(QtWidgets.QMessageBox.Ok) info_box.setIcon(QtWidgets.QMessageBox.Information) info_box.setWindowTitle("New system submitted") info_box.setText( "The new system is being processed now, please wait! \n" "Especially when LaTeX is used for the labels this may take some time and the " "program might seem unresponsive!") info_box.setModal(False) info_box.show() QtCore.QCoreApplication.processEvents() # Processing equations equation = (x_string, y_string) system = System(self, equation) self.systems.insert(0, system) self.save_tmp_system() myLogger.message("------ new system created ------") myLogger.message( " x' = " + str(system.equation.what_is_my_system()[0])) myLogger.message( " y' = " + str(system.equation.what_is_my_system()[1]) + "\n", ) try: info_box.close() except RuntimeError: # if dialog has already been closed by the user pass except BaseException as exc: QtWidgets.QMessageBox.critical( self, "Error!", "An error occured while processing the system. " "Detailed error message: \n %s" % exc) myLogger.error_message(str(exc)) else: myLogger.error_message("Please check system!")
def submit(self): """ This function gets called after clicking on the submit button """ try: xtxt = str(self.xDotLineEdit.text()) ytxt = str(self.yDotLineEdit.text()) except UnicodeEncodeError as exc: myLogger.warn_message("UnicodeEncodeError! Please check input.") myLogger.debug_message(str(exc)) else: cond1 = str(self.xDotLineEdit.text()) != "" cond2 = str(self.yDotLineEdit.text()) != "" if cond1 and cond2: x_string = str(self.xDotLineEdit.text()) y_string = str(self.yDotLineEdit.text()) equation = (x_string, y_string) system = System(self, equation) self.systems.insert(0, system) self.save_tmp_system() myLogger.message("------ new system created ------") myLogger.message(" x' = " + str(system.equation.what_is_my_system()[0])) myLogger.message( " y' = " + str(system.equation.what_is_my_system()[1]) + "\n", ) else: myLogger.error_message("Please check system!")
def __init__(self, parent, plot_pp, plot_x, plot_y): assert isinstance(plot_pp, Canvas) assert isinstance(plot_x, Canvas) assert isinstance(plot_y, Canvas) # for deleting lineedits/etc. from parent class self.parent = parent self.plot_pp = plot_pp self.plot_x = plot_x self.plot_y = plot_y # register_graph plot_pp myEquilibria.register_graph(self.plot_pp) myNullclines.register_graph(self.plot_pp) myTrajectories.register_graph(self, self.plot_pp, self.plot_x, self.plot_y) myStreamlines.register_graph(self, self.plot_pp) myVectorfield.register_graph(self, self.plot_pp) # read initial values: vector field, streamlines, nullclines self.vf_toggle = myConfig.get_boolean("Vectorfield", "vf_onByDefault") self.nc_toggle = myConfig.get_boolean("Nullclines", "nc_onByDefault") self.sl_toggle = myConfig.get_boolean("Streamlines", "stream_onByDefault") myLogger.debug_message("Graph class initialized")
def submit(self): """ This function gets called after clicking on the submit button """ try: xtxt = str(self.xDotLineEdit.text()) ytxt = str(self.yDotLineEdit.text()) except UnicodeEncodeError as exc: myLogger.warn_message("UnicodeEncodeError! Please check input.") myLogger.debug_message(str(exc)) else: cond1 = str(self.xDotLineEdit.text()) != "" cond2 = str(self.yDotLineEdit.text()) != "" if cond1 and cond2: x_string = str(self.xDotLineEdit.text()) y_string = str(self.yDotLineEdit.text()) equation = (x_string, y_string) system = System(self, equation) self.systems.insert(0, system) self.save_tmp_system() myLogger.message("------ new system created ------") myLogger.message(" x' = " + str(system.equation.what_is_my_system()[0])) myLogger.message(" y' = " + str(system.equation.what_is_my_system()[1]) + "\n", ) else: myLogger.error_message("Please check system!")
def update(self): """ This function plots streamlines. """ self.remove() if self.tgl: xmin, xmax, ymin, ymax = self.myWidget.Plot.canvas.axes.axis() N = int(myConfig.read("Streamlines", "stream_gridPointsInX")) M = int(myConfig.read("Streamlines", "stream_gridPointsInY")) stream_linewidth = float(myConfig.read("Streamlines", "stream_linewidth")) stream_color = str(myConfig.read("Streamlines", "stream_color")) stream_density = float(myConfig.read("Streamlines", "stream_density")) a = np.linspace(xmin, xmax, N) b = np.linspace(ymin, ymax, M) X1, Y1 = np.meshgrid(a, b) try: DX1, DY1 = self.myWidget.mySystem.equation.rhs([X1, Y1]) streamplot = self.myWidget.Plot.canvas.axes.streamplot(X1, Y1, DX1, DY1, density=stream_density, linewidth=stream_linewidth, color=stream_color) self.sl_stack.append(streamplot) myLogger.message("Streamplot created") except: myLogger.debug_message("No system yet") self.myWidget.Plot.canvas.draw()
def __init__(self, parent=None): super(PyplaneMainWindow, self).__init__() QtWidgets.QWidget.__init__(self, parent) self.setupUi(self) self.setWindowTitle('PyPlane') myLogger.register_output(self.logField) # Check if LaTeX and dvipng is installed on the system. This # is required in order to ensure that advanced formatting in # matplotlib works correctly (\left, \begin{array} etc.) self.latex_installed = myHelpers.check_if_latex() # Embed SettingsWidget: self.mySettings = SettingsWidget() self.SettingsLayout.addWidget(self.mySettings) self.fct_stack = [] self.linearization_stack = [] self.systems = [] self.xDotLabel.setText("\u1E8B(x,y) = ") self.yDotLabel.setText("\u1E8F(x,y) = ") try: test = myConfig.read("Test", "test_var") except: test = "Could not load config file. Please check existence" myLogger.debug_message("Loading config file: " + test)
def rhs(self, z, t=0.): """ this function represents the system """ # falls endliche fluchtzeit: # abfrage ob norm(x)>10**5 norm_z = pl.norm(z) if norm_z > self.max_norm: myLogger.debug_message("norm(z) exceeds " + str(self.max_norm) + ": norm(z) = " + str(norm_z)) z2 = (z / norm_z) * self.max_norm self.x, self.y = z2 else: self.x, self.y = z xx_dot = self.x_dot(self.x, self.y) yy_dot = self.y_dot(self.x, self.y) zDot = xx_dot, yy_dot # norm_zDot = norm(zDot) # # if norm_zDot>self.max_norm*1e3: # myLogger.debug_message("norm(z dot) exceeds 1e10: norm(z')="+str(norm_zDot)) return np.array([xx_dot, yy_dot])
def onclick(self, event): """ This function is in charge of the mouse-click behaviour. A left mouse button click is recognized, the mouse location serves as an initial condition for trajectories. """ # TODO: check if try/except is the best thing to do here! if not self.canvas.zoomMode: event1 = event.xdata is not None event2 = event.ydata is not None button = event.button == 1 if not self.myWidget.Equilibria.tgl: # event.xdata and event.ydata are initial conditions for integration # mouse click will also be recognized if clicked outside of the graph area, so filter that: if event1 and event2 and button: forward, backward = self.myWidget.trajectory_direction() if self.myWidget.mySystem.Trajectories.plot_trajectory([event.xdata, event.ydata], forward, backward): myLogger.message("New initial condition: " + str(event.xdata) + ", " + str(event.ydata)) else: pass else: # equilibrium point if event1 and event2 and button: equilibrium_point = self.myWidget.Equilibria.find_equilibrium([event.xdata, event.ydata]) if equilibrium_point is not None: # is this supposed to be here? pass #~ jacobian = self.myWidget.Equilibria.approx_ep_jacobian(equilibrium_point) #~ self.myWidget.mySystem.myPyplane.new_linearized_system(self.myWidget.mySystem, jacobian, equilibrium_point) else: myLogger.debug_message("in zoom mode")
def __init__(self, parent=None): super(PyplaneMainWindow, self).__init__() QtGui.QWidget.__init__(self, parent) self.setupUi(self) self.setWindowTitle('PyPlane') myLogger.register_output(self.logField) # Check if LaTeX and dvipng is installed on the system. This # is required in order to ensure that advanced formatting in # matplotlib works correctly (\left, \begin{array} etc.) self.latex_installed = myHelpers.check_if_latex() # Embed SettingsWidget: self.mySettings = SettingsWidget() self.SettingsLayout.addWidget(self.mySettings) self.fct_stack = [] self.linearization_stack = [] self.systems = [] self.xDotLabel.setText(u"\u1E8B(x,y) = ") self.yDotLabel.setText(u"\u1E8F(x,y) = ") try: test = myConfig.read("Test", "test_var") except: test = "Could not load config file. Please check existence" myLogger.debug_message("Loading config file: " + test)
def __init__(self, parent, latex_installed): self.myWidget = parent plot_background = myConfig.read("Plotting", "plot_background") plot_CanvasBackground = str(myConfig.read("Plotting", "plot_CanvasBackground")) plot_fontSize = int(myConfig.read("Plotting", "plot_fontSize")) plot_topOfPlot = float(myConfig.read("Plotting", "plot_topOfPlot")) plot_leftOfPlot = 0.12#float(myConfig.read("Plotting", "plot_leftOfPlot")) plot_rightOfPlot = float(myConfig.read("Plotting", "plot_rightOfPlot")) plot_bottomOfPlot = 0.1#float(myConfig.read("Plotting", "plot_bottomOfPlot")) self.fig = pl.Figure(facecolor=plot_background) pl.matplotlib.rc('font', size=plot_fontSize) # Check if LaTeX and dvipng are installed on this system since this # is required by matplotlib for fine rendering. If it is not installed # only basic rendering will be done in the following rc('text', usetex=latex_installed) # ALIASING # TODO: read aliasing variables: # pl.matplotlib.rc('lines', antialiased=False) # pl.matplotlib.rc('text', antialiased=False) # pl.matplotlib.rc('patch', antialiased=False) self.axes = self.fig.add_subplot(111) # Matplotlib 2.0 vs. 1.5 behavior... try: self.axes.set_facecolor(plot_CanvasBackground) # Matplotlib >= 2 except AttributeError: self.axes.set_axis_bgcolor(plot_CanvasBackground) # Matplotlib < 2 # matplotlib background transparent (issues on old versions?) if myConfig.get_boolean("Plotting", "plot_backgroundTransparent"): self.fig.frameon = False self.adjust = self.fig.subplots_adjust(top=plot_topOfPlot, left=plot_leftOfPlot, right=plot_rightOfPlot, bottom=plot_bottomOfPlot) FigureCanvas.__init__(self, self.fig) self.setParent(parent) self.navigationToolbar = Toolbar(self) # TODO: rather as a real toolbar: # self.toolbar = NavigationToolbar(self, self.myWidget.mpl_layout, coordinates=True) # self.myWidget.mplvl.addWidget(self.toolbar) FigureCanvas.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) # zoom mode on/off self.zoomMode = False myLogger.debug_message(str(self) + ": initialized")
def add(self): try: fct_string = str(self.mySystem.myPyplane.yLineEdit.text()) except UnicodeEncodeError as exc: myLogger.error_message("input error!") myLogger.debug_message(str(exc)) fct_string = str(self.mySystem.myPyplane.yLineEdit.text()) if fct_string != "": try: self.fct_expr = sp.sympify(fct_string) self.fct = sp.lambdify((self.x, self.y), self.fct_expr, 'numpy') xmin, xmax, ymin, ymax = self.mySystem.Phaseplane.Plot.canvas.axes.axis( ) # plot the function for an x-interval twice as big as the current window deltax = (xmax - xmin) / 2 deltay = (ymax - ymin) / 2 plot_xmin = xmin - deltax plot_xmax = xmax + deltax plot_ymin = ymin - deltay plot_ymax = ymax + deltay pts_in_x = int(myConfig.read("Functions", "fct_gridPointsInX")) pts_in_y = int(myConfig.read("Functions", "fct_gridPointsInY")) fct_color = myConfig.read("Functions", "fct_color") fct_linewidth = float( myConfig.read("Functions", "fct_linewidth")) x = np.arange(plot_xmin, plot_xmax, (xmax - xmin) / pts_in_x) y = np.arange(plot_ymin, plot_ymax, (ymax - ymin) / pts_in_y) X, Y = np.meshgrid(x, y) myfunc = self.fct(X, Y) # TODO: plots like y=1/x have a connection between -inf and +inf that is not actually there! # plot function and put on function-stack new_fct = self.mySystem.Phaseplane.Plot.canvas.axes.contour( X, Y, myfunc, [0], zorder=100, linewidths=fct_linewidth, colors=fct_color) # new_fct = self.myGraph.plot_pp.axes.plot(xvalue, yvalue, label="fct", color="green") self.fct_stack.append(new_fct) self.mySystem.Phaseplane.Plot.update() myLogger.message("function plot: 0 = " + fct_string) except Exception as error: # TODO: use handle_exception for this myLogger.error_message(str(error)) else: myLogger.error_message("Please enter function.")
def new_value(self, lineedit, section, variable): # read lineedit #QtCore.pyqtRemoveInputHook() #embed() new_value = str(lineedit.text()) # write config file myConfig.write(section, variable, new_value) myLogger.debug_message("New value for " + str(variable) + ":" + new_value)
def get_current_system(self): index = self.tabWidget.currentIndex() if (len(self.systems) > 0) and (index != len(self.systems)): system = self.systems[index] return system else: myLogger.debug_message("No system chosen.") return None
def handle_exception(error): myLogger.error_message("Error: An Python Exception occured.") myLogger.debug_message(str(type(error))) myLogger.debug_message(str(error)) myLogger.message("See the log file config/logmessages.txt for full traceback ") exc_type, exc_value, exc_tb = sys.exc_info() lines = traceback.format_exception(exc_type, exc_value, exc_tb) tb_msg = "".join(lines) myLogger.append_to_file(tb_msg)
def __init__(self, parent, latex_installed): self.myWidget = parent plot_background = myConfig.read("Plotting", "plot_background") plot_CanvasBackground = str(myConfig.read("Plotting", "plot_CanvasBackground")) plot_fontSize = int(myConfig.read("Plotting", "plot_fontSize")) plot_topOfPlot = float(myConfig.read("Plotting", "plot_topOfPlot")) plot_leftOfPlot = float(myConfig.read("Plotting", "plot_leftOfPlot")) plot_rightOfPlot = float(myConfig.read("Plotting", "plot_rightOfPlot")) plot_bottomOfPlot = float(myConfig.read("Plotting", "plot_bottomOfPlot")) self.fig = pl.Figure(facecolor=plot_background) pl.matplotlib.rc('font', size=plot_fontSize) # Check if LaTeX and dvipng are installed on this system since this # is required by matplotlib for fine rendering. If it is not installed # only basic rendering will be done in the following rc('text', usetex=latex_installed) # ALIASING # TODO: read aliasing variables: # pl.matplotlib.rc('lines', antialiased=False) # pl.matplotlib.rc('text', antialiased=False) # pl.matplotlib.rc('patch', antialiased=False) self.axes = self.fig.add_subplot(111) self.axes.set_axis_bgcolor(plot_CanvasBackground) # matplotlib background transparent (issues on old versions?) if myConfig.get_boolean("Plotting", "plot_backgroundTransparent"): self.fig.frameon = False self.adjust = self.fig.subplots_adjust(top=plot_topOfPlot, left=plot_leftOfPlot, right=plot_rightOfPlot, bottom=plot_bottomOfPlot) FigureCanvas.__init__(self, self.fig) self.setParent(parent) self.navigationToolbar = Toolbar(self) # TODO: rather as a real toolbar: #~ self.toolbar = NavigationToolbar(self, self.myWidget.mpl_layout, coordinates=True) #~ self.myWidget.mplvl.addWidget(self.toolbar) FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) # zoom mode on/off self.zoomMode = False myLogger.debug_message(str(self) + ": initialized")
def settings_item_clicked(self, index): # TODO: May be we should change this mechanism to a clear model-view # process. Maybe a tree view is appropriate? self.remove_visible_items() # set section title self.section = str(index.data()) # what was sec_elab supposed to mean? section_description = self.descr[self.section] self.SetupSectionTitle.setText(section_description) # iterate over items in section items = myConfig.config.items(self.section) self.remove_visible_items() for i in items: # add qlabel and a qlineedit to gui label = QtWidgets.QLabel() label.setObjectName(i[0]) label.setFixedWidth(300) # this does not seem to work, but why?: label.setAlignment(QtCore.Qt.AlignRight) # QtCore.pyqtRemoveInputHook() # embed() try: item_description = str(self.descr[i[0]][0]) except KeyError: myLogger.debug_message( "Key %s not found in description list (key deprecated or invalid), ignoring...!" % (i[0])) label.setText(str(item_description) + ":") label.setAlignment(QtCore.Qt.AlignRight) value = myConfig.read(self.section, i[0]) if (value.lower() == "true") | (value.lower() == "false"): input_widget = self.create_boolean_combo_box(i[0], value) elif "color" in item_description.lower(): input_widget = self.create_color_chooser(i[0], value) else: input_widget = self.create_line_edit(i[0], value) # add to stack_visible: # what was the 0 for? self.stack_visible.append([label, 0]) # self.stack_visible.append([lineedit, self.section, str(i[0])]) # self.add_to_layout(label, lineedit) self.stack_visible.append([input_widget, self.section, str(i[0])]) self.add_to_layout(label, input_widget)
def clear(self): self.canvas.axes.clear() if myConfig.get_boolean(self._section, self._token + "showGrid"): self.canvas.axes.grid() if myConfig.get_boolean(self._section, self._token + "showMinorTicks"): self.canvas.axes.minorticks_on() else: self.canvas.axes.minorticks_off() if not myConfig.get_boolean(self._section, self._token + "showTTicks"): self.canvas.axes.zaxis.set_ticks([]) if not myConfig.get_boolean(self._section, self._token + "showXTicks"): self.canvas.axes.xaxis.set_ticks([]) if not myConfig.get_boolean(self._section, self._token + "showYTicks"): self.canvas.axes.yaxis.set_ticks([]) if myConfig.get_boolean(self._section, self._token + "showTitle"): title_x_dot = sp.latex( self.myWidget.mySystem.equation.what_is_my_system()[0]) title_y_dot = sp.latex( self.myWidget.mySystem.equation.what_is_my_system()[1]) self.canvas.axes.set_title("$\\dot{x} = " + title_x_dot + "$\n$\\dot{y} = " + title_y_dot + "$") else: self.canvas.fig.subplots_adjust(top=0.99) if myConfig.get_boolean(self._section, self._token + "showXLabel"): xlabel = "$x$" label_fontsize = myConfig.read(self._section, self._token + "labelFontSize") self.canvas.axes.set_xlabel(xlabel, fontsize=label_fontsize) if myConfig.get_boolean(self._section, self._token + "showYLabel"): label_fontsize = myConfig.read(self._section, self._token + "labelFontSize") ylabel = "$y$" self.canvas.axes.set_ylabel(ylabel, fontsize=label_fontsize) if myConfig.get_boolean(self._section, self._token + "showTLabel"): label_fontsize = myConfig.read(self._section, self._token + "labelFontSize") tlabel = "$t$" self.canvas.axes.set_zlabel(tlabel, fontsize=label_fontsize) if not myConfig.get_boolean(self._section, self._token + "showSpines"): for spine in self.canvas.axes.spines.itervalues(): spine.set_visible(False) self.update() myLogger.debug_message("3d graph cleared")
def set_window_range(self, Graph): """ This function changes the window range of Graph. """ # TODO: check if there is a better way to do this? --> put lineedit stuff in PyplaneMainWindow or MainApp! try: # phase plane flag pp_flag = False if Graph == self.plot_pp: xmin = float(self.parent.PP_xminLineEdit.text()) xmax = float(self.parent.PP_xmaxLineEdit.text()) ymin = float(self.parent.PP_yminLineEdit.text()) ymax = float(self.parent.PP_ymaxLineEdit.text()) # set flag pp_flag = True elif Graph == self.plot_x: xmin = float(self.parent.X_tminLineEdit.text()) xmax = float(self.parent.X_tmaxLineEdit.text()) ymin = float(self.parent.X_xminLineEdit.text()) ymax = float(self.parent.X_xmaxLineEdit.text()) # elif Graph == self.plot_y: else: xmin = float(self.parent.Y_tminLineEdit.text()) xmax = float(self.parent.Y_tmaxLineEdit.text()) ymin = float(self.parent.Y_yminLineEdit.text()) ymax = float(self.parent.Y_ymaxLineEdit.text()) if xmin < xmax and ymin < ymax: Graph.axes.set_xlim(xmin, xmax) Graph.axes.set_ylim(ymin, ymax) if pp_flag: # self.update_graph(Graph) myVectorfield.update() myStreamlines.update() #self.update_vectorfield() #self.update_streamlines() myNullclines.update() else: myLogger.error_message("Please check window size input!") except Exception as error: myLogger.error_message("Error!") myLogger.debug_message(str(type(error))) myLogger.debug_message(str(error)) # update_all graph self.update_graph(Graph)
def settings_item_clicked(self, index): # TODO: May be we should change this mechanism to a clear model-view # process. Maybe a tree view is appropriate? self.remove_visible_items() # set section title self.section = str(index.data()) # what was sec_elab supposed to mean? section_description = self.descr[self.section] self.SetupSectionTitle.setText(section_description) # iterate over items in section items = myConfig.config.items(self.section) self.remove_visible_items() for i in items: # add qlabel and a qlineedit to gui label = QtWidgets.QLabel() label.setObjectName(i[0]) label.setFixedWidth(300) # this does not seem to work, but why?: label.setAlignment(QtCore.Qt.AlignRight) # QtCore.pyqtRemoveInputHook() # embed() try: item_description = str(self.descr[i[0]][0]) except KeyError: myLogger.debug_message("Key %s not found in description list (key deprecated or invalid), ignoring...!" % (i[0])) label.setText(str(item_description) + ":") label.setAlignment(QtCore.Qt.AlignRight) value = myConfig.read(self.section, i[0]) if (value.lower() == "true") | (value.lower() == "false"): input_widget = self.create_boolean_combo_box(i[0], value) elif "color" in item_description.lower(): input_widget = self.create_color_chooser(i[0], value) else: input_widget = self.create_line_edit(i[0], value) # add to stack_visible: # what was the 0 for? self.stack_visible.append([label, 0]) # self.stack_visible.append([lineedit, self.section, str(i[0])]) # self.add_to_layout(label, lineedit) self.stack_visible.append([input_widget, self.section, str(i[0])]) self.add_to_layout(label, input_widget)
def update(self): """ this function will show nullclines """ self.remove() if self.tgl: # get axis limits xmin, xmax, ymin, ymax = self.myWidget.Plot.canvas.axes.axis() pts_in_x = int(myConfig.read("Nullclines", "nc_gridPointsInX")) pts_in_y = int(myConfig.read("Nullclines", "nc_gridPointsInY")) nc_color_xdot = myConfig.read("Nullclines", "nc_color_xdot") nc_color_ydot = myConfig.read("Nullclines", "nc_color_ydot") nc_linewidth = float(myConfig.read("Nullclines", "nc_linewidth")) a = np.arange(xmin, xmax, (xmax - xmin) / pts_in_x) b = np.arange(ymin, ymax, (xmax - xmin) / pts_in_y) X1, Y1 = np.meshgrid(a, b) try: DX1, DY1 = self.myWidget.mySystem.equation.rhs([X1, Y1]) nullclines_xdot = self.myWidget.Plot.canvas.axes.contour( X1, Y1, DX1, levels=[0], linewidths=nc_linewidth, colors=nc_color_xdot) nullclines_ydot = self.myWidget.Plot.canvas.axes.contour( X1, Y1, DY1, levels=[0], linewidths=nc_linewidth, colors=nc_color_ydot) # proxy artist for legend proxy_x_nc = pyplot.Rectangle((0, 0), 1, 1, fc=nc_color_xdot) proxy_y_nc = pyplot.Rectangle((0, 0), 1, 1, fc=nc_color_ydot) self.myWidget.Plot.canvas.axes.legend( [proxy_x_nc, proxy_y_nc], ["x-Nullclines", "y-Nullclines"], bbox_to_anchor=(0., 1.02, 1., .102), loc=2, prop={'size': 8}, frameon=False) self.nc_stack.append(nullclines_xdot) self.nc_stack.append(nullclines_ydot) except: myLogger.debug_message("Please submit system.") # refresh graph self.myWidget.Plot.canvas.draw()
def handle_exception(error): myLogger.error_message("Error: An Python Exception occured.") myLogger.debug_message(str(type(error))) myLogger.debug_message(str(error)) myLogger.message( "See the log file config/logmessages.txt for full traceback ") exc_type, exc_value, exc_tb = sys.exc_info() lines = traceback.format_exception(exc_type, exc_value, exc_tb) tb_msg = "".join(lines) myLogger.append_to_file(tb_msg)
def submit(self): """ This function gets called after clicking on the submit button """ try: xtxt = str(self.xDotLineEdit.text()) ytxt = str(self.yDotLineEdit.text()) except UnicodeEncodeError as exc: myLogger.warn_message("UnicodeEncodeError! Please check input.") myLogger.debug_message(str(exc)) else: cond1 = str(self.xDotLineEdit.text()) != "" cond2 = str(self.yDotLineEdit.text()) != "" if cond1 and cond2: # set right hand side, print rhs to logfield, solve, # then plot vector field # initialize system mySystem.__init__() # set rhs x_string = str(self.xDotLineEdit.text()) y_string = str(self.yDotLineEdit.text()) mySystem.set_rhs(x_string, y_string) try: # write to tmp file: self.save_system('library/tmp.ppf') # clear figure, if there is any self.myGraph.clear() # delete linearization tabs (index 3 to n) if len(self.linearization_stack) > 0: for i in xrange(0, len(self.linearization_stack)): index = 3 + len(self.linearization_stack) - i self.tabWidget.removeTab(index) #reset stack self.linearization_stack = [] myLogger.debug_message("All linearization tabs removed.") self.initializing() myLogger.message("------ new system created ------") myLogger.message(" x' = " + str(mySystem.what_is_my_system()[0])) myLogger.message(" y' = " + str(mySystem.what_is_my_system()[1]) + "\n", ) except Exception as error: handle_exception(error) else: myLogger.error_message("No system entered")
def add(self): try: fct_string = str(self.mySystem.myPyplane.yLineEdit.text()) except UnicodeEncodeError as exc: myLogger.error_message("input error!") myLogger.debug_message(str(exc)) fct_string = str(self.mySystem.myPyplane.yLineEdit.text()) if fct_string != "": try: self.fct_expr = sp.sympify(fct_string) self.fct = sp.lambdify((self.x, self.y), self.fct_expr, 'numpy') xmin, xmax, ymin, ymax = self.mySystem.Phaseplane.Plot.canvas.axes.axis() # plot the function for an x-interval twice as big as the current window deltax = (xmax - xmin) / 2 deltay = (ymax - ymin) / 2 plot_xmin = xmin - deltax plot_xmax = xmax + deltax plot_ymin = ymin - deltay plot_ymax = ymax + deltay pts_in_x = int(myConfig.read("Functions", "fct_gridPointsInX")) pts_in_y = int(myConfig.read("Functions", "fct_gridPointsInY")) fct_color = myConfig.read("Functions", "fct_color") fct_linewidth = float(myConfig.read("Functions", "fct_linewidth")) x = np.arange(plot_xmin, plot_xmax, (xmax - xmin) / pts_in_x) y = np.arange(plot_ymin, plot_ymax, (ymax - ymin) / pts_in_y) X, Y = np.meshgrid(x, y) myfunc = self.fct(X, Y) # TODO: plots like y=1/x have a connection between -inf and +inf that is not actually there! # plot function and put on function-stack new_fct = self.mySystem.Phaseplane.Plot.canvas.axes.contour(X, Y, myfunc, [0], zorder=100, linewidths=fct_linewidth, colors=fct_color) # new_fct = self.myGraph.plot_pp.axes.plot(xvalue, yvalue, label="fct", color="green") self.fct_stack.append(new_fct) self.mySystem.Phaseplane.Plot.update() myLogger.message("function plot: 0 = " + fct_string) except Exception as error: # TODO: use handle_exception for this myLogger.error_message(str(error)) else: myLogger.error_message("Please enter function.")
def submit(self): """ This function gets called after clicking on the submit button """ myLogger.message("New system submitted...") try: xtxt = str(self.xDotLineEdit.text()) ytxt = str(self.yDotLineEdit.text()) except UnicodeEncodeError as exc: myLogger.warn_message("UnicodeEncodeError! Please check input.") myLogger.debug_message(str(exc)) else: cond1 = str(self.xDotLineEdit.text()) != "" cond2 = str(self.yDotLineEdit.text()) != "" if cond1 and cond2: x_string = str(self.xDotLineEdit.text()) y_string = str(self.yDotLineEdit.text()) try: # Non-modal (!) Box intended for calming down the user... info_box = QtWidgets.QMessageBox(self) info_box.setAttribute(Qt.WA_DeleteOnClose) info_box.setStandardButtons(QtWidgets.QMessageBox.Ok) info_box.setIcon(QtWidgets.QMessageBox.Information) info_box.setWindowTitle("New system submitted") info_box.setText("The new system is being processed now, please wait! \n" "Especially when LaTeX is used for the labels this may take some time and the " "program might seem unresponsive!") info_box.setModal(False) info_box.show() QtCore.QCoreApplication.processEvents() # Processing equations equation = (x_string, y_string) system = System(self, equation) self.systems.insert(0, system) self.save_tmp_system() myLogger.message("------ new system created ------") myLogger.message(" x' = " + str(system.equation.what_is_my_system()[0])) myLogger.message(" y' = " + str(system.equation.what_is_my_system()[1]) + "\n", ) try: info_box.close() except RuntimeError: # if dialog has already been closed by the user pass except BaseException as exc: QtWidgets.QMessageBox.critical(self, "Error!", "An error occured while processing the system. " "Detailed error message: \n %s" % exc) myLogger.error_message(str(exc)) else: myLogger.error_message("Please check system!")
def onclick(self, event): """ This function is in charge of the mouse-click behaviour. A left mouse button click is recognized, the mouse location serves as an initial condition for trajectories. """ #TODO: check if try/except is the best thing to do here! if not self.plot_pp.zoomMode: try: mySystem except: # only capture mouse click if system exists myLogger.error_message("Please enter system.") else: cond1 = mySystem.x_dot is not None cond2 = mySystem.x_dot is not None cond3 = str(self.parent.xDotLineEdit.text()) != "" cond4 = str(self.parent.yDotLineEdit.text()) != "" if cond1 and cond2 and cond3 and cond4: event1 = event.xdata is not None event2 = event.ydata is not None button = event.button == 1 if not myEquilibria.eqp_toggle: # event.xdata and event.ydata are initial conditions for integration # mouse click will also be recognized if clicked outside of the graph area, so filter that: if event1 and event2 and button: forward, backward = self.trajectory_direction() if myTrajectories.plot_trajectory( [event.xdata, event.ydata], forward, backward): myLogger.message("New initial condition: " + str(event.xdata) + ", " + str(event.ydata)) else: pass else: # equilibrium point if event1 and event2 and button: equilibrium_point = myEquilibria.find_equilibrium( [event.xdata, event.ydata]) if equilibrium_point is not None: self.parent.add_linearization_tab( equilibrium_point) else: # only capture mouse click if system exists myLogger.error_message("Please enter system.") else: myLogger.debug_message("in zoom mode")
def remove_all(self): """ this function removes every trajectory in y(x), x(t) and y(t) """ for i in self.traj_dict: # i is the next key for j in range(0, len(self.traj_dict[i])): # j is a list element from the traj_stack try: self.traj_dict[i].pop()[0].remove() except Exception as error: myLogger.error_message("Could not delete trajectory") myLogger.debug_message(str(type(error))) myLogger.debug_message(str(error)) self.mySystem.update()
def get_boolean(self, section, variable): if self.config.has_option(str(section), str(variable)): value = self.config.getboolean(str(section), str(variable)) myLogger.debug_message(str(variable) + "\": " + str(value) + " (config)") return value elif str(variable) in self.decr: #self.descr.has_key(str(variable)): # fallback value value = self.descr[str(variable)][1] myLogger.debug_message(str(variable) + "\": " + str(value) + " (fallback)") return value else: #pass myLogger.error_message("Error! A variable was called that does not exist.")
def read(self, section, variable): if self.config.has_option(str(section), str(variable)): value = self.config.get(str(section), str(variable)) # TODO: check if the config value is of same type as fallback value myLogger.debug_message(str(variable) + "\": " + str(value) + " (config)") return value elif str(variable) in self.descr: # fallback value value = self.descr[str(variable)][1] myLogger.debug_message(str(variable) + "\": " + str(value) + " (fallback)") return value else: #pass myLogger.error_message("Error! A variable was called that does not exist.")
def remove_all(self): """ this function removes every trajectory in y(x), x(t) and y(t) """ for i in self.traj_dict: # i is the next key for j in xrange(0, len(self.traj_dict[i])): # j is a list element from the traj_stack try: self.traj_dict[i].pop()[0].remove() except Exception as error: myLogger.error_message("Could not delete trajectory") myLogger.debug_message(str(type(error))) myLogger.debug_message(str(error)) self.mySystem.update()
def clear(self): """ This function clears every graph. """ # reset plots for graph in [self.plot_pp, self.plot_x, self.plot_y]: self.clear_graph(graph) # empty stacks self.vf_stack = [] myStreamlines.clear_stack() myTrajectories.clear_stack() myEquilibria.clear_stack() myNullclines.clear_stack() myLogger.debug_message("graphs cleared!\n")
def clear(self): self.canvas.axes.clear() if myConfig.get_boolean(self._section, self._token + "showGrid"): self.canvas.axes.grid() if myConfig.get_boolean(self._section, self._token + "showMinorTicks"): self.canvas.axes.minorticks_on() else: self.canvas.axes.minorticks_off() if not myConfig.get_boolean(self._section, self._token + "showTTicks"): self.canvas.axes.zaxis.set_ticks([]) if not myConfig.get_boolean(self._section, self._token + "showXTicks"): self.canvas.axes.xaxis.set_ticks([]) if not myConfig.get_boolean(self._section, self._token + "showYTicks"): self.canvas.axes.yaxis.set_ticks([]) if myConfig.get_boolean(self._section, self._token + "showTitle"): title_x_dot = sp.latex(self.myWidget.mySystem.equation.what_is_my_system()[0]) title_y_dot = sp.latex(self.myWidget.mySystem.equation.what_is_my_system()[1]) self.canvas.axes.set_title("$\\dot{x} = " + title_x_dot + "$\n$\\dot{y} = " + title_y_dot + "$") else: self.canvas.fig.subplots_adjust(top=0.99) if myConfig.get_boolean(self._section, self._token + "showXLabel"): xlabel = "$x$" label_fontsize = myConfig.read(self._section, self._token + "labelFontSize") self.canvas.axes.set_xlabel(xlabel, fontsize=label_fontsize) if myConfig.get_boolean(self._section, self._token + "showYLabel"): label_fontsize = myConfig.read(self._section, self._token + "labelFontSize") ylabel = "$y$" self.canvas.axes.set_ylabel(ylabel, fontsize=label_fontsize) if myConfig.get_boolean(self._section, self._token + "showTLabel"): label_fontsize = myConfig.read(self._section, self._token + "labelFontSize") tlabel = "$t$" self.canvas.axes.set_zlabel(tlabel, fontsize=label_fontsize) if not myConfig.get_boolean(self._section, self._token + "showSpines"): for spine in self.canvas.axes.spines.itervalues(): spine.set_visible(False) self.update() myLogger.debug_message("3d graph cleared")
def update(self): """ this function will show nullclines """ self.remove() if self.nc_toggle: # get axis limits xmin, xmax, ymin, ymax = self.plot_pp.axes.axis() pts_in_x = int(myConfig.read("Nullclines", "nc_gridPointsInX")) pts_in_y = int(myConfig.read("Nullclines", "nc_gridPointsInY")) nc_color_xdot = myConfig.read("Nullclines", "nc_color_xdot") nc_color_ydot = myConfig.read("Nullclines", "nc_color_ydot") nc_linewidth = float(myConfig.read("Nullclines", "nc_linewidth")) a = np.arange(xmin, xmax, (xmax - xmin) / pts_in_x) b = np.arange(ymin, ymax, (xmax - xmin) / pts_in_y) X1, Y1 = np.meshgrid(a, b) try: DX1, DY1 = mySystem.rhs([X1, Y1]) nullclines_xdot = self.plot_pp.axes.contour(X1, Y1, DX1, levels=[0], linewidths=nc_linewidth, colors=nc_color_xdot) nullclines_ydot = self.plot_pp.axes.contour(X1, Y1, DY1, levels=[0], linewidths=nc_linewidth, colors=nc_color_ydot) # proxy artist for legend proxy_x_nc = pyplot.Rectangle((0, 0), 1, 1, fc=nc_color_xdot) proxy_y_nc = pyplot.Rectangle((0, 0), 1, 1, fc=nc_color_ydot) self.plot_pp.axes.legend([proxy_x_nc, proxy_y_nc], ["x-Nullclines", "y-Nullclines"], bbox_to_anchor=(0., 1.02, 1., .102), loc=2, prop={'size': 8}, frameon=False) self.nc_stack.append(nullclines_xdot) self.nc_stack.append(nullclines_ydot) except: myLogger.debug_message("Please submit system.") # refresh graph self.plot_pp.draw()
def update(self): """ This function updates the vectorfield in the phase plane. """ self.remove() if self.tgl: # get axis limits xmin, xmax, ymin, ymax = self.myWidget.Plot.canvas.axes.axis() N = int(myConfig.read("Vectorfield", "vf_gridPointsInX")) M = int(myConfig.read("Vectorfield", "vf_gridPointsInY")) vf_color = str(myConfig.read("Vectorfield", "vf_color")) vf_arrowHeadWidth = float( myConfig.read("Vectorfield", "vf_arrowHeadWidth")) vf_arrowHeadLength = float( myConfig.read("Vectorfield", "vf_arrowHeadLength")) vf_arrowWidth = float(myConfig.read("Vectorfield", "vf_arrowWidth")) vf_arrowPivot = str(myConfig.read("Vectorfield", "vf_arrowPivot")) a = np.linspace(xmin - xmin / N, xmax - xmax / N, N) b = np.linspace(ymin - ymin / M, ymax - ymax / M, M) X1, Y1 = np.meshgrid(a, b) try: DX1, DY1 = self.myWidget.mySystem.equation.rhs([X1, Y1]) M = np.hypot(DX1, DY1) M[M == 0] = 1. DX1_mix, DY1_mix = DX1 / M, DY1 / M quiver = self.myWidget.Plot.canvas.axes.quiver( X1, Y1, DX1_mix, DY1_mix, angles='xy', headwidth=vf_arrowHeadWidth, headlength=vf_arrowHeadLength, width=vf_arrowWidth, pivot=vf_arrowPivot, color=vf_color) self.stack.append(quiver) myLogger.message("vector field created") except: myLogger.debug_message("Please enter system.") self.myWidget.Plot.update()
def onclick(self, event): """ This function is in charge of the mouse-click behaviour. A left mouse button click is recognized, the mouse location serves as an initial condition for trajectories. """ #TODO: check if try/except is the best thing to do here! if not self.plot_pp.zoomMode: try: mySystem except: # only capture mouse click if system exists myLogger.error_message("Please enter system.") else: cond1 = mySystem.x_dot is not None cond2 = mySystem.x_dot is not None cond3 = str(self.parent.xDotLineEdit.text()) != "" cond4 = str(self.parent.yDotLineEdit.text()) != "" if cond1 and cond2 and cond3 and cond4: event1 = event.xdata is not None event2 = event.ydata is not None button = event.button == 1 if not myEquilibria.eqp_toggle: # event.xdata and event.ydata are initial conditions for integration # mouse click will also be recognized if clicked outside of the graph area, so filter that: if event1 and event2 and button: forward, backward = self.trajectory_direction() if myTrajectories.plot_trajectory([event.xdata, event.ydata], forward, backward): myLogger.message("New initial condition: " + str(event.xdata) + ", " + str(event.ydata)) else: pass else: # equilibrium point if event1 and event2 and button: myEquilibria.find_equilibrium([event.xdata, event.ydata]) else: # only capture mouse click if system exists myLogger.error_message("Please enter system.") else: myLogger.debug_message("in zoom mode")
def __init__(self, parent=None): plot_background = myConfig.read("Plotting", "plot_background") plot_CanvasBackground = str(myConfig.read("Plotting", "plot_CanvasBackground")) plot_fontSize = int(myConfig.read("Plotting", "plot_fontSize")) plot_topOfPlot = float(myConfig.read("Plotting", "plot_topOfPlot")) plot_leftOfPlot = float(myConfig.read("Plotting", "plot_leftOfPlot")) plot_rightOfPlot = float(myConfig.read("Plotting", "plot_rightOfPlot")) plot_bottomOfPlot = float(myConfig.read("Plotting", "plot_bottomOfPlot")) self.fig = pl.Figure(facecolor=plot_background) pl.matplotlib.rc('font', size=plot_fontSize) # use latex rc('text', usetex=True) # ALIASING # TODO: read aliasing variables: # pl.matplotlib.rc('lines', antialiased=False) # pl.matplotlib.rc('text', antialiased=False) # pl.matplotlib.rc('patch', antialiased=False) self.axes = self.fig.add_subplot(111) self.axes.set_axis_bgcolor(plot_CanvasBackground) # matplotlib background transparent (issues on old versions?) if myConfig.get_boolean("Plotting", "plot_backgroundTransparent"): self.fig.frameon = False self.adjust = self.fig.subplots_adjust(top=plot_topOfPlot, left=plot_leftOfPlot, right=plot_rightOfPlot, bottom=plot_bottomOfPlot) FigureCanvas.__init__(self, self.fig) self.setParent(parent) self.navigationToolbar = Toolbar(self) FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) # zoom mode on/off self.zoomMode = False myLogger.debug_message(str(self) + ": initialized")
def create_trajectory(self): try: initial_condition = self.mySystem.Phaseplane.read_init() forward, backward = self.mySystem.Phaseplane.trajectory_direction() cond1 = initial_condition[0] is not None cond2 = initial_condition[1] is not None # check if trajectory with initial_condition exists already cond3 = not str(initial_condition) in self.traj_dict if cond1 and cond2 and cond3: self.plot_trajectory(initial_condition, forward, backward) myLogger.message("New initial condition: " + str(initial_condition[0]) + ", " + str(initial_condition[1])) except Exception as error: myLogger.error_message("Could not create trajectory") myLogger.debug_message(str(type(error))) myLogger.debug_message(str(error))
def __init__(self): self.config = configparser.ConfigParser() self.config.optionxform = str __dir__ = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) filepath = os.path.abspath(os.path.join(__dir__, 'config/default')) try: data = self.config.read(filepath) except Exception as exc: myLogger.warn_message("input error!") myLogger.debug_message(str(exc)) print("Input error") # fallback values # read config-descriptions from dictionary self.descr = {} with open('core/config_description.py', 'r') as configdict: configdata = configdict.read() self.descr = ast.literal_eval(configdata) # Ensure that the configuration loaded from disk matches the requirments from the config description: # Missing sections and options are added and set to the default values from the config description # (See config_description.py) # sectioninfo[0] -> Name of section, sectioninfo[1] -> Prefix of the section options for sectioninfo in self.descr["sectionlist"]: # Add missing sections if not self.config.has_section(sectioninfo[0]): self.config.add_section(sectioninfo[0]) # Get the option names that BEGIN with the correct prefix associated with the section optionnames = [ optionname for optionname in self.descr if sectioninfo[1] in optionname[0:len(sectioninfo[1])] ] # Add missing options and set them to the default values for optionname in optionnames: if not self.config.has_option(sectioninfo[0], optionname): self.config.set(sectioninfo[0], optionname, str(self.descr[optionname][1]))
def clear(self): self.canvas.axes.clear() if myConfig.get_boolean(self._section, self._token + "showGrid"): self.canvas.axes.grid() if myConfig.get_boolean(self._section, self._token + "showMinorTicks"): self.canvas.axes.minorticks_on() else: self.canvas.axes.minorticks_off() if not myConfig.get_boolean(self._section, self._token + "showXTicks"): self.canvas.axes.xaxis.set_ticks([]) if not myConfig.get_boolean(self._section, self._token + "showYTicks"): self.canvas.axes.yaxis.set_ticks([]) if myConfig.get_boolean(self._section, self._token + "showXLabel"): pp_label_fontsize = myConfig.read(self._section, self._token + "labelFontSize") xlabel = "$%s$" % self.myWidget.xlabel_str self.canvas.axes.set_xlabel(xlabel, fontsize=pp_label_fontsize) if myConfig.get_boolean(self._section, self._token + "showTitle"): title_x_dot = sp.latex(self.myWidget.mySystem.equation.what_is_my_system()[0]) title_y_dot = sp.latex(self.myWidget.mySystem.equation.what_is_my_system()[1]) self.canvas.axes.set_title("$\\dot{x} = " + title_x_dot + "$\n$\\dot{y} = " + title_y_dot + "$") else: self.canvas.fig.subplots_adjust(top=0.99) if myConfig.get_boolean(self._section, self._token + "showYLabel"): pp_label_fontsize = myConfig.read(self._section, self._token + "labelFontSize") ylabel = "$%s$" % self.myWidget.ylabel_str self.canvas.axes.set_ylabel(ylabel, fontsize=pp_label_fontsize) # TODO (jcw): Check if this can be removed (together with Graph class) # if not myConfig.get_boolean(self._section, self._token + "showSpines"): # for spine in Graph.axes.spines.values(): # spine.set_visible(False) self.update() myLogger.debug_message("Graph cleared")
def update(self): """ This function updates the vectorfield in the phase plane. """ self.remove() if self.tgl: # get axis limits xmin, xmax, ymin, ymax = self.myWidget.Plot.canvas.axes.axis() N = int(myConfig.read("Vectorfield", "vf_gridPointsInX")) M = int(myConfig.read("Vectorfield", "vf_gridPointsInY")) vf_color = str(myConfig.read("Vectorfield", "vf_color")) vf_arrowHeadWidth = float(myConfig.read("Vectorfield", "vf_arrowHeadWidth")) vf_arrowHeadLength = float(myConfig.read("Vectorfield", "vf_arrowHeadLength")) vf_arrowWidth = float(myConfig.read("Vectorfield", "vf_arrowWidth")) vf_arrowPivot = str(myConfig.read("Vectorfield", "vf_arrowPivot")) a = np.linspace(xmin - xmin / N, xmax - xmax / N, N) b = np.linspace(ymin - ymin / M, ymax - ymax / M, M) X1, Y1 = np.meshgrid(a, b) try: DX1, DY1 = self.myWidget.mySystem.equation.rhs([X1, Y1]) M = np.hypot(DX1, DY1) M[M == 0] = 1. DX1_mix, DY1_mix = DX1 / M, DY1 / M quiver = self.myWidget.Plot.canvas.axes.quiver(X1, Y1, DX1_mix, DY1_mix, angles='xy', headwidth=vf_arrowHeadWidth, headlength=vf_arrowHeadLength, width=vf_arrowWidth, pivot=vf_arrowPivot, color=vf_color) self.stack.append(quiver) myLogger.message("vector field created") except: myLogger.debug_message("Please enter system.") self.myWidget.Plot.update()
def remove(self): """ This function removes Streamlines if existent. """ if len(self.sl_stack) != 0: for i in range(0, len(self.sl_stack)): sl = self.sl_stack.pop() try: sl.lines.remove() except: pass #sl_arrows.remove() doesn't work # doesn't work either: del sl.arrows # as long as no other patches are used: self.myWidget.Plot.canvas.axes.patches = [] myLogger.message("Streamlines removed") else: myLogger.debug_message("No streamlines to delete")
def __init__(self): self.config = ConfigParser.ConfigParser() self.config.optionxform = str __dir__ = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) filepath = os.path.abspath(os.path.join(__dir__, 'config/default')) try: data = self.config.read(filepath) except Exception as exc: myLogger.warn_message("input error!") myLogger.debug_message(str(exc)) print("Input error") # fallback values # read config-descriptions from dictionary self.descr = {} with open('core/config_description.py', 'r') as dict: data = dict.read() self.descr = ast.literal_eval(data)
def remove(self): """ This function removes the vector field if existent. """ if len(self.stack) != 0: for i in xrange(0, len(self.stack)): try: self.stack.pop().remove() myLogger.message("Vector field removed") except Exception as error: myLogger.debug_message("Couldn't delete vector field") myLogger.debug_message(str(type(error))) myLogger.debug_message(str(error)) else: myLogger.debug_message("No vector field to delete")
def update(self): """ This function plots streamlines. """ self.remove() if self.tgl: xmin, xmax, ymin, ymax = self.myWidget.Plot.canvas.axes.axis() N = int(myConfig.read("Streamlines", "stream_gridPointsInX")) M = int(myConfig.read("Streamlines", "stream_gridPointsInY")) stream_linewidth = float( myConfig.read("Streamlines", "stream_linewidth")) stream_color = str(myConfig.read("Streamlines", "stream_color")) stream_density = float( myConfig.read("Streamlines", "stream_density")) a = np.linspace(xmin, xmax, N) b = np.linspace(ymin, ymax, M) X1, Y1 = np.meshgrid(a, b) try: DX1, DY1 = self.myWidget.mySystem.equation.rhs([X1, Y1]) streamplot = self.myWidget.Plot.canvas.axes.streamplot( X1, Y1, DX1, DY1, density=stream_density, linewidth=stream_linewidth, color=stream_color) self.sl_stack.append(streamplot) myLogger.message("Streamplot created") except: myLogger.debug_message("No system yet") self.myWidget.Plot.canvas.draw()
def remove_function_from_plot(self): if len(self.fct_stack) != 0: for i in xrange(0, len(self.fct_stack)): fct = self.fct_stack.pop().collections for j in xrange(0, len(fct)): try: fct[j].remove() except Exception as error: myLogger.debug_message("couldn't delete function") myLogger.debug_message(str(type(error))) myLogger.debug_message(str(error)) myLogger.message("functions removed") else: myLogger.debug_message("no function to delete") self.myGraph.update_graph(self.myGraph.plot_pp)
def remove_all(self): if len(self.fct_stack) != 0: for i in range(0, len(self.fct_stack)): fct = self.fct_stack.pop().collections for j in range(0, len(fct)): try: fct[j].remove() except Exception as error: myLogger.debug_message("couldn't delete function") myLogger.debug_message(str(type(error))) myLogger.debug_message(str(error)) myLogger.message("functions removed") else: myLogger.debug_message("no function to delete") self.mySystem.Phaseplane.Plot.update()