class BasicGrapher(grapher.BasicGrapher): """Documentation string for Basic Grapher A simple graphing widget By Randy P. and Bart O.""" def __init__(self, parent=None, **kw): self.ax = Figure(figsize=(4.3, 3.0)).gca() self.ax2d = self.ax self.ax3d = None if kw.get("hide"): self.canvas = FigureCanvasAgg(self.ax.get_figure()) else: self.canvas = FigureCanvasTkAggRedraw(self, parent) tk_widget = self.canvas.get_tk_widget() self.quit = tk_widget.quit self.bind = tk_widget.bind self.unbind = tk_widget.unbind self.winfo_rootx = tk_widget.winfo_rootx self.winfo_rooty = tk_widget.winfo_rooty self.ax.set_autoscale_on(0) self.postscript = self.canvas.print_figure self.savefig = self.ax.get_figure().savefig self.redrawlabels = 0 callback = self.__optionCallback grapher.BasicGrapher.__init__(self, parent, callback, **kw) optionDefaults = {} optionDefaults["xticks"] = (None, callback) optionDefaults["yticks"] = (None, callback) optionDefaults["zticks"] = (None, callback) optionDefaults["background"] = ("white", callback) optionAliases = {} optionAliases["bg"] = "background" self.addOptions(**optionDefaults) self.addAliases(**optionAliases) for key in [ "grid", "decorations", "xlabel", "ylabel", "zlabel", "xlabel_fontsize", "ylabel_fontsize", "zlabel_fontsize", "minx", "maxx", "miny", "maxy", "minz", "maxz", "width", "height", "left_margin", "right_margin", "top_margin", "bottom_margin" ]: self.__optionCallback(key, self.cget(key), []) matplotlib.rcParams["axes.edgecolor"] = self.cget("foreground") def pack(self, **kw): self.canvas.get_tk_widget().pack(kw) def update(self): if isinstance(self.canvas, FigureCanvasTkAggRedraw): self.canvas.get_tk_widget().update() FigureCanvasTkAgg.draw(self.canvas) else: self.canvas.draw() def __optionCallback(self, key, value, options): if key in [ "minx", "maxx", "miny", "maxy", "minz", "maxz", "realwidth", "realheight", "azimuth", "elevation", "left_margin", "right_margin", "top_margin", "bottom_margin" ]: self.redrawlabels = 1 if key[:3] in ["min", "max"]: minc = self.cget("min" + key[3]) maxc = self.cget("max" + key[3]) if minc < maxc: func = None if self.ax is self.ax3d: func = getattr(self.ax, "set_" + key[3] + "lim3d") self._cur_lims = (Axes.get_xlim(self.ax), Axes.get_ylim(self.ax)) elif key[3] != 'z': func = getattr(self.ax, "set_" + key[3] + "lim") if func is not None: func(minc, maxc) tickskey = key[3] + "ticks" ticksval = self.cget(tickskey) if ticksval is not None: self.__optionCallback(tickskey, ticksval, options) elif key == "realwidth": lm = float(self.cget("left_margin")) rm = float(self.cget("right_margin")) self.ax.get_figure().subplots_adjust(left=lm / value, right=1 - rm / value) elif key == "realheight": tm = float(self.cget("top_margin")) bm = float(self.cget("bottom_margin")) top = 1 - tm / value bottom = bm / value if top > bottom: self.ax.get_figure().subplots_adjust(top=top, bottom=bottom) elif key == "left_margin": fig = self.ax.get_figure() width = fig.get_figwidth() * fig.get_dpi() fig.subplots_adjust(left=value / width) elif key == "right_margin": fig = self.ax.get_figure() width = fig.get_figwidth() * fig.get_dpi() fig.subplots_adjust(right=1 - value / width) elif key == "top_margin": fig = self.ax.get_figure() height = fig.get_figheight() * fig.get_dpi() fig.subplots_adjust(top=1 - value / height) elif key == "bottom_margin": fig = self.ax.get_figure() height = fig.get_figheight() * fig.get_dpi() fig.subplots_adjust(bottom=value / height) elif self.ax is self.ax3d: elev = self.cget("elevation") azim = self.cget("azimuth") if elev is not None or azim is not None: self.ax.view_init(elev, azim) elif key == "grid": if value in ["yes", True]: self.ax.grid(color=self.cget("foreground")) else: self.ax.grid(False) elif key in ["width", "height"]: if isinstance(self.canvas, FigureCanvasTkAggRedraw): self.canvas.get_tk_widget()[key] = value else: fig = self.ax.get_figure() if key == "width": fig.set_figwidth(float(value) / fig.get_dpi()) self._configNoDraw(realwidth=value) else: fig.set_figheight(float(value) / fig.get_dpi()) self._configNoDraw(realheight=value) elif key == "top_title": fontsize = self.cget("top_title_fontsize") if fontsize is None: self.ax.set_title(value) else: self.ax.set_title(value, fontsize=fontsize) elif key == "top_title_fontsize": title = self.cget("top_title") if title is not None: self.ax.set_title(title, fontsize=value) elif key in ["background", "bg"]: if hasattr(self.ax, 'set_facecolor'): # matplotlib >= 2.0 self.ax.set_facecolor(value) else: self.ax.set_axis_bgcolor(value) elif key in ["foreground", "fg"]: matplotlib.rcParams["axes.edgecolor"] = self.cget("foreground") self.redrawlabels = 1 if self.cget("grid") in ["yes", True]: self.ax.grid(color=value) elif key == "color_list": color_list = value.split() i = 0 for d in self.data: if d["newsect"] is None or d["newsect"]: i = i + 1 if d["color"] is None: color = i else: color = d["color"] d["mpline"].set_color(color_list[color % len(color_list)]) elif key == "decorations": if value: self.ax.set_axis_on() else: self.ax.set_axis_off() elif key == "use_symbols": self.plotsymbols() elif key == "use_labels": self.plotlabels() elif key in ["xlabel", "ylabel", "zlabel"]: if value is None: value = "" fontsize = self.cget(key + "_fontsize") if hasattr(self.ax, "set_" + key): func = getattr(self.ax, "set_" + key) if fontsize is None: func(value) else: func(value, fontsize=fontsize) elif key in ["xlabel_fontsize", "ylabel_fontsize", "zlabel_fontsize"]: label = self.cget(key[:6]) if hasattr(self.ax, "set_" + key[:6]): func = getattr(self.ax, "set_" + key[:6]) if value is None: func(label) else: func(label, fontsize=value) elif key in ["xticks", "yticks", "zticks"]: if value is None: if self.ax is self.ax3d: axis = getattr(self.ax, "w_" + key[0] + "axis") axis.set_major_locator(AutoLocator()) elif key == "xticks": self.ax.set_xscale('linear') else: self.ax.set_yscale('linear') else: min = self.cget("min" + key[0]) max = self.cget("max" + key[0]) ticks = [ min + ((max - min) * i) / float(value - 1) for i in range(value) ] if self.ax is self.ax3d: axis = getattr(self.ax, "w_" + key[0] + "axis") axis.set_major_locator(FixedLocator(ticks)) elif key == "xticks": self.ax.set_xticks(ticks) elif key == "yticks": self.ax.set_yticks(ticks) def _delAllData(self): for d in self.data: if "mpline" in d: self.ax.lines.remove(d["mpline"]) self.data = [] # set type for next data try: zcolumn = self.cget(self.cget("type") + "_z") except Tkinter.TclError: #in regression test return oldax = self.ax if zcolumn is None or Axes3D is None: if zcolumn is not None: self._configNoDraw({self.cget("type") + "_z": None}) print("\nmatplotlib 0.98.x does not support 3D plots.") print("Plotting only the first two coordinates.") if self.ax is self.ax3d: # restore zoom mode new_zoom_mode = self.zoom_mode self.ax = self.ax2d else: if self.ax3d is None: self.ax3d = Axes3D(self.ax.get_figure()) try: self.ax3d.set_autoscale_on(0) except TypeError: #Matplotlib 1.1 bug self.ax2d.set_autoscale_on(0) self.ax3d.set_autoscalez_on(0) if self.ax is self.ax2d: # remember zoom mode and disable zoom if isinstance(self.canvas, FigureCanvasTkAggRedraw): self.zoom_mode = self.toolbar.mode new_zoom_mode = '' self.ax = self.ax3d if self.ax is not oldax: if (isinstance(self.canvas, FigureCanvasTkAggRedraw) and new_zoom_mode != self.toolbar.mode): if "rect" in new_zoom_mode: self.toolbar.zoom() elif "pan" in new_zoom_mode: self.toolbar.pan() elif "rect" in self.toolbar.mode: self.toolbar.zoom() elif "pan" in self.toolbar.mode: self.toolbar.pan() #copy settings from 3d to 2d or vice versa for key in ("grid", "decorations", "xlabel", "ylabel", "zlabel", "xticks", "yticks", "zticks", "minx", "maxx", "miny", "maxy", "minz", "maxz", "azimuth", "elevation", "top_title", "background"): self.__optionCallback(key, self.cget(key), []) def _delData(self, index): if "mpline" in data[index]: self.ax.lines.remove(data[index]["mpline"]) del self.data[index] def clear(self): if len(self.ax.get_figure().axes) > 0: self.ax.get_figure().delaxes(self.ax.get_figure().axes[0]) def draw(self): if self.redrawlabels: self.plotlabels() if len(self.ax.get_figure().axes) == 0: self.ax.get_figure().add_axes(self.ax) if isinstance(self.canvas, FigureCanvasTkAggRedraw): FigureCanvasTkAgg.draw(self.canvas) else: self.canvas.draw() def plot(self): color_list = self.cget("color_list").split() # data line_width = self.cget("line_width") dashes = list(map(float, self.cget("dashes"))) i = -1 for d in self.data: if d["newsect"] is None or d["newsect"]: i = i + 1 curve = "curve:%d" % (i, ) if self.ax is self.ax2d: v = [d["x"], d["y"]] else: v = [d["x"], d["y"], d["z"]] if d["color"] is None: color = i else: color = d["color"] kw = {'color': color_list[color % len(color_list)]} if len(v[0]) == 1: # If we only have one point we draw a small circle or a pixel if self.cget("type") == "solution": marker = 'o' else: marker = ',' v.append(marker) #tags=("data_point:%d"%(0,),curve,"data") else: stable = d["stable"] #tags=(curve,"data") kw['lw'] = line_width if stable is not None and not stable: kw.update({'ls': '--', 'dashes': dashes}) if self.ax is self.ax2d: self.ax.plot(*v, **kw) else: self.ax.plot3D(*v, **kw) d["mpline"] = self.ax.lines[-1] if len(self.ax.get_figure().axes) == 0: self.ax.get_figure().add_axes(self.ax) def __setitem__(self, key, value): self.configure(**{key: value}) def __getitem__(self, key): return self.cget(key)