def __init__(self, width, height): self.root = Tk.Tk() self.root.wm_title("Double Slider Test") self.plot = Figure(figsize = (width+1, height+2), dpi=72) self.axes = self.plot.add_subplot(111) self.canvas = FigureCanvasTkAgg(self.plot, master=self.root) self.canvas.get_tk_widget().grid(row=0) self.nav_plot = Figure(figsize = (width+1, 2), dpi=72) self.nav_axes = self.nav_plot.add_subplot(111) self.nav_canvas = FigureCanvasTkAgg(self.nav_plot, master=self.root) self.nav_canvas.get_tk_widget().grid(row=1) self.nav_plot.subplots_adjust(bottom=0.2) self.agg_canvas = self.nav_canvas.get_tk_widget() self.slider = DoubleSlider(self.root, round=lambda x: round(x, 2), left_bound=2.0, right_bound=3.0) self.slider.grid(row=2, sticky=Tk.W+Tk.E+Tk.N+Tk.S) data = [(2.0, 0.6), (2.1, 0.9), (2.2, 0.7), (2.3, 0.8), (2.4, 0.5), (2.6, 0.2), (2.7, 0.3), (2.8, 0.6), (2.9, 0.4), (3.0, 0.1)] self.axes.set_xbound(2.0, 3.0) self.axes.add_collection(LineCollection([data])) self.nav_axes.set_xbound(2.0, 3.0) self.nav_axes.add_collection(LineCollection([data]))
def create_thumbnail(infile, thumbfile, width=180, height=180, xoffset=0, yoffset=0, zoom=1, cx=0.5, cy=0.6, dpi=100): from matplotlib import image from matplotlib.pyplot import Figure baseout, extout = os.path.splitext(thumbfile) im = image.imread(infile) thumb = padded_thumbnail(im, (height, width), (yoffset, xoffset), zoom) extension = extout.lower() if extension == '.png': from matplotlib.backends.backend_agg \ import FigureCanvasAgg as FigureCanvas elif extension == '.pdf': from matplotlib.backends.backend_pdf \ import FigureCanvasPDF as FigureCanvas elif extension == '.svg': from matplotlib.backends.backend_svg \ import FigureCanvasSVG as FigureCanvas else: raise ValueError("Can only handle extensions 'png', 'svg' or 'pdf'") fig = Figure(figsize=(float(width) / dpi, float(height) / dpi), dpi=dpi) canvas = FigureCanvas(fig) ax = fig.add_axes([0, 0, 1, 1], aspect='auto', frameon=False, xticks=[], yticks=[]) ax.imshow(thumb, aspect='auto', resample=True, interpolation='bilinear') fig.savefig(thumbfile, dpi=dpi) return fig
def __init__(self, parent=None, width=5.0, height=4.0, dpi=100): fig = Figure((width, height), dpi=dpi) self.axes = fig.add_subplot(1, 1, 1) FigureCanvas.__init__(self, fig) self.setParent(parent) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.updateGeometry() self.plot()
def initUI(self): self.parent.title("Interactive LUX visualization") self.pack(fill=BOTH, expand=1) self.color_frame = Frame(self, border=1) self.color_frame.pack(side=LEFT) self.frame = Frame(self.color_frame, border=1, relief=SUNKEN, width=100, height=100) #self.frame.place(x=160, y=30) self.frame.pack(side=TOP) self.frame.config(bg=self.hex_color) self.btn = Button(self.color_frame, text="Select Color", command=self.onChoose) self.btn.pack(side=TOP) #self.btn.place(x=30, y=30) self.display = Text(self, border=1, relief=SUNKEN, width=30, height=5) #self.display.place(x=280, y=30) self.display.pack(side=LEFT,fill=Y,expand=1) self.update_output() self.fig = Figure(figsize=(10,4), dpi=100) self.replot() self.canvas = FigureCanvasTkAgg(self.fig, master=self) self.canvas.show() self.canvas.get_tk_widget().pack(side=LEFT, fill=BOTH, expand=1) self.canvas._tkcanvas.pack(side='top', fill='both', expand=1)
def save_figure(fig: plt.Figure, destination: str, extra_artist: mpl.artist.Artist=None): name = Path(destination) if extra_artist is not None: extra_args = {"extra_artists": (extra_artist, ), "bbox_inches": "tight"} else: extra_args = {} for extension in [".pdf", ".svgz", ".png"]: if extension != "png": fig.savefig(str(name.with_suffix(extension)), **extra_args) else: fig.savefig(str(name.with_suffix(extension)), dpi=300, **extra_args)
def saveplot(self,filename,**kwargs): dpi = kwargs.pop('dpi',72) format = kwargs.pop('format','png') backend_canvas = kwargs.pop('backend_canvas',FigureCanvasAgg) ins_orig = mpl.rcParams['svg.image_noscale'] mpl.rcParams['svg.image_noscale'] = True fig = Figure() canvas = backend_canvas(fig) ax = fig.add_subplot(111) self.plot(axes=ax,**kwargs) fig.savefig(filename,dpi=dpi,format=format) # Put svg image config back to original #mpl.rcParams['svg.embed_char_paths'] = ecp_orig mpl.rcParams['svg.image_noscale'] = ins_orig return filename
def initUI(self): self.parent.title("Interactive LUX visualization") self.pack(fill=BOTH, expand=1) self.color_frame = Frame(self, border=1) self.color_frame.pack(side=LEFT) probe_title_var = StringVar(); probe_title_label = Label(self.color_frame, textvariable=probe_title_var, justify=CENTER, font = "Helvetica 16 bold italic") probe_title_var.set("Color Probe X"); probe_title_label.pack(side=TOP) self.hsv_var = StringVar() self.hsv_label = Label(self.color_frame, textvariable=self.hsv_var,justify=LEFT) h,s,v = self.hsv_color self.hsv_var.set("Hue: %2.1f \nSaturation: %2.1f \nValue: %2.1f" % (h*360,s*100,v*100)) self.hsv_label.pack(side=TOP) self.frame = Frame(self.color_frame, border=1, relief=SUNKEN, width=200, height=200) self.frame.pack(side=TOP) self.frame.config(bg=self.hex_color) self.frame.bind("<Button-1>",self.onChoose) self.btn = Button(self.color_frame, text="Select Color", command=self.onChoose) self.btn.pack(side=TOP) posterior_title_var = StringVar(); posterior_title_label = Label(self.color_frame, textvariable=posterior_title_var, justify=CENTER, font = "Helvetica 16 bold italic") posterior_title_var.set("\n\nLUX's Posterior"); posterior_title_label.pack(side=TOP) Label(self.color_frame, text="Double click to show details \n(Wait time dependent on computer)").pack(side=TOP) my_font = tkFont.Font(family="Courier", size=10) self.display = Listbox(self.color_frame, border=1, relief=SUNKEN, width=30, height=25, font=my_font) self.display.pack(side=TOP,fill=Y,expand=1) self.display.bind("<Double-Button-1>",self.onSelect) self.display_btn = Button(self.color_frame, text="Show details", command=self.onSelect) self.display_btn.pack(side=TOP) self.update_output() self.fig = Figure(figsize=(10,4), dpi=100) self.canvas = FigureCanvasTkAgg(self.fig, master=self) self.canvas.show() self.canvas.get_tk_widget().pack(side=LEFT, fill=BOTH, expand=1) self.canvas._tkcanvas.pack(side='top', fill='both', expand=1)
def draw_coordinate_axes(ax: plt.Figure, traj: trajectory.PosePath3D, plot_mode: PlotMode, marker_scale: float = 0.1, x_color: str = "r", y_color: str = "g", z_color: str = "b") -> None: """ Draws a coordinate frame axis for each pose of a trajectory. :param ax: plot axis :param traj: trajectory.PosePath3D or trajectory.PoseTrajectory3D object :param plot_mode: PlotMode value :param marker_scale: affects the size of the marker (1. * marker_scale) :param x_color: color of the x-axis :param y_color: color of the y-axis :param z_color: color of the z-axis """ if marker_scale <= 0: return unit_x = np.array([1 * marker_scale, 0, 0, 1]) unit_y = np.array([0, 1 * marker_scale, 0, 1]) unit_z = np.array([0, 0, 1 * marker_scale, 1]) # Transform start/end vertices of each axis to global frame. x_vertices = np.array([[p[:3, 3], p.dot(unit_x)[:3]] for p in traj.poses_se3]) y_vertices = np.array([[p[:3, 3], p.dot(unit_y)[:3]] for p in traj.poses_se3]) z_vertices = np.array([[p[:3, 3], p.dot(unit_z)[:3]] for p in traj.poses_se3]) n = traj.num_poses # Concatenate all line segment vertices in order x, y, z. vertices = np.concatenate((x_vertices, y_vertices, z_vertices)).reshape( (n * 2 * 3, 3)) # Concatenate all colors per line segment in order x, y, z. colors = np.array(n * [x_color] + n * [y_color] + n * [z_color]) markers = colored_line_collection(vertices, colors, plot_mode, step=2) ax.add_collection(markers)
def npsPlotByKey(pkg: NotePkg, fig:plt.Figure = None, shape: Tuple = None, window=1000, stride=None, title=True, legend=True, barKwargs=None) -> plt.Figure: """ This creates an NPS Plot with the axes. :param pkg: Any Note Package :param fig: The figure to plot on, if None, we use gcf() :param shape: The shape of the axes to take. (rows, columns) :param window: The window of the roll :param stride: The stride length of the roll :param title: Whether to show the key titles :param legend: Whether to show legend. False to show none, True to show on first, 'all' to show on all :param barKwargs: The kwargs to pass into plot() """ if fig is None: fig = plt.gcf() if barKwargs is None: barKwargs = {} keys = pkg.maxColumn() + 1 # This gives us the keys if shape is None: rows = keys cols = 1 shape = (rows, cols) else: assert shape[0] * shape[1] >= keys, "Shape must be able to hold all keys." ax: np.ndarray = fig.subplots(nrows=shape[0], ncols=shape[1], sharex='all', sharey='all') ax = ax.flatten() for key in range(keys): if legend == 'all': npsPlot(pkg.inColumns([key]), ax=ax[key], window=window, stride=stride, legend=True, barKwargs=barKwargs) elif legend is True and key == 0: npsPlot(pkg.inColumns([key]), ax=ax[key], window=window, stride=stride, legend=True, barKwargs=barKwargs) else: npsPlot(pkg.inColumns([key]), ax=ax[key], window=window, stride=stride, legend=False, barKwargs=barKwargs) ax: List[plt.Axes] if title: ax[key].set_title(f"Key: {key}") fig.tight_layout() return fig
def plot_cfg_barplot(fig: plt.Figure, commit_report: tp.Optional[CommitReport], draw_cf: bool, cr_meta: tp.Optional[CommitReportMeta]) -> None: """Generates a bar plot that visualizes the IN/OUT control-flow/data-flow edges of regions.""" if commit_report is None: return ylimit = None if draw_cf: data = generate_inout_cfg_cf(commit_report, cr_meta) color_palette = sns.color_palette(["#004949", "#920000"]) if cr_meta is not None: ylimit = cr_meta.cf_ylimit else: data = generate_inout_cfg_df(commit_report, cr_meta) color_palette = sns.color_palette(["#006DDB", "#920000"]) if cr_meta is not None: ylimit = cr_meta.df_ylimit if data.empty: LOG.error("CommitReport has no CF interactions") return data['Region'] = data['Region'].apply(lambda x: x[0:6]) plt.figure(fig.number) plt.clf() if ylimit is not None: plt.ylim(0, ylimit) bar_p = sns.barplot(x="Region", y="Amount", hue="Direction", data=data, palette=color_palette) for label in bar_p.get_xticklabels(): label.set_rotation(90) label.set_family("monospace") fig.add_subplot(bar_p)
def add_figure(self, fig: plt.Figure, caption: str, width: str = r"\textwidth"): """Adds a pyplot figure to the document Arguments: fig: pyplot figure handle caption: caption to add to the figure in the document width: the width of the image, by default this is set to the pagewidth """ figfn = self.docdir / "{}.png".format(self.figidx) fig.tight_layout() fig.savefig(figfn, dpi=120) self.figidx += 1 figtex = figtemplate.format(fn=figfn.name, caption=caption, width=width) self.add_body(figtex)
def save_figure(fig: plt.Figure, destination: str, extra_artist: mpl.artist.Artist = None): name = Path(destination) if extra_artist is not None: extra_args = { "extra_artists": (extra_artist, ), "bbox_inches": "tight" } else: extra_args = {} for extension in [".pdf", ".svgz", ".png"]: if extension != "png": fig.savefig(str(name.with_suffix(extension)), **extra_args) else: fig.savefig(str(name.with_suffix(extension)), dpi=300, **extra_args)
def __plot_A_i(self, fig: plt.Figure, ax: plt.Axes) -> None: """ Plot all points and highlight the sampled sets A_i. :param fig: The matplotlib figure to plot on. :param ax: The matplotlib axes to plot on. """ ax.cla() colors = get_cmap("Dark2").colors ax.set_prop_cycle(color=colors) for i, a_i in enumerate(self.A): ax.scatter([v.i for v in a_i], [v.j for v in a_i], s=8, marker="o", label="A_{}".format(i)) ax.set_title("Sampled sets A_i") ax.legend(bbox_to_anchor=(1.05, 1.0), loc='upper left') plt.tight_layout() fig.show()
def showPlot3D(self, x, y, z): fig = Figure(dpi=100, frameon=False) a = fig.add_subplot(111, projection='3d') a.plot_surface(x, y, z, rstride=4, cstride=4, linewidth=0, color='b') canvas = FigureCanvas(fig) #Makes possible to rotate the plot a.mouse_init() self.update_canvas(canvas)
def show_simplicial_complex(self, x: ndarray, y: ndarray, C, f: plt.Figure, rows, cols, i, titl): ambient_dim = x.shape[1] if ambient_dim == 2: ax = f.add_subplot(rows, cols, i) elif ambient_dim == 3: ax = Axes3D(f) self._complex_fig_common(ax, x, y, C, titl) return 1
def plot_roc(roc: ROC, title: str = "", label: str = "", show=False, save=False, fig: plt.Figure = None): if fig is None: fig = plt.figure() ax = fig.add_axes([0.1, 0.1, 0.85, 0.8]) else: ax = fig.get_axes() assert len(ax) == 1 ax = ax[0] lw = 2 fpr, tpr, _ = roc ax.plot(fpr, tpr, lw=lw, label=label) ax.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--') ax.set(xlabel='FPR', ylabel='TPR', ylim=[0.0, 1.05], xlim=[0.0, 1.0]) ax.set_title(title, fontsize=15) ax.legend(loc="lower right") # fig.tight_layout() if show: fig.show() if save: fig.savefig(f'figs/{title}_{label}.png') return fig
def save_plot( figure: plt.Figure, function_name: str, dates: List[str], time_step: str, window: str, K_value: str, sim: bool = False, ) -> None: """Saves plot in png files. Saves the plot generated in the functions of the epochs_analysis module in png files. :param figure: figure object that is going to be save. :param function_name: name of the function that generates the plot. :param dates: List of the interval of dates to be analyzed (i.e. ['1980-01-01', '2020-12-31']). :param time_step: time step of the data (i.e. '1m', '1h', '1d', '1wk', '1mo'). :param window: window time to compute the volatility (i.e. '25'). :param K_value: number of companies to be used (i.e. '80', 'all'). :return: None -- The function save the plot in a file and does not return a value. """ if sim: figure.savefig(f"../plot/epochs_sim/{function_name}_win_{window}.png") else: # Saving plot data figure.savefig( f"../plot/epochs_sim/{function_name}_{dates[0]}" + f"_{dates[1]}_step_{time_step}_win_{window}_K" + "_{K_value}.png" ) print("Plot Saved") print()
def update_image(self): """ Update the canvas with the next image in the sequence Returns ------- None. """ fig = Figure(figsize=(5, 5)) self.ax = fig.add_subplot(111) self.imname = self.images[self.img_idx] self.image = imread(self.imname) try: self.ax.imshow(self.image, cmap='viridis') except TypeError: self.current_slice = 0 self.max_slice = self.image.shape[0] - 1 self.ax.imshow(self.image[self.current_slice], cmap='viridis') self.ax.axis("off") self.canvas = FigureCanvasTkAgg(fig, master=self.master) self.canvas.get_tk_widget().pack()
def init_frame(img: ndarray, ratio: float, fig: Figure, ax: Axes, title) -> Tuple[AxesImage, Colorbar, Text]: image_slice = get_slice(img, ratio=ratio) # the bigger alpha, the image would become more black true_args = dict(vmin=0, vmax=255, cmap="bone", alpha=0.8) im = ax.imshow(image_slice, animated=True, **true_args) # im = ax.imshow(image_slice, animated=True) ax.set_xticks([]) ax.set_yticks([]) title = ax.set_title(title) cb = fig.colorbar(im, ax=ax) return im, cb, title
def showPlot2D(self, x, y, squared): if squared: asp = 'equal' else: asp = 'auto' fig = Figure(dpi=100, frameon=False) a = fig.add_subplot(111, aspect=asp) a.plot(x, y) canvas = FigureCanvas(fig) self.update_canvas(canvas)
def export( fig: plt.Figure, filename: Union[str, os.fspath], target_dir: str = "plots/", file_formats: Tuple[str] = (".pdf", ".png") ) -> None: """ Convenience function for saving a matplotlib figure. :param fig: A matplotlib figure. :param filename: Filename of the plot without .pdf suffix. :param file_formats: Tuple of file formats specifying the format figure will be saved as. :param target_dir: Directory where the plot will be saved in. Default is './plots/'. :return: None """ if not os.path.isdir(target_dir): os.makedirs(target_dir) for file_format in file_formats: fig.savefig(os.path.join(target_dir, f'{filename}{file_format}'), bbox_inches="tight")
def save_plot(figure: plt.Figure, function_name: str, dates: List[str], time_step: str) -> None: """Saves plot in png files. Saves the plot generated in the functions of the exact_distributions_covariance_analysis module in png files. :param figure: figure object that is going to be save. :param function_name: name of the function that generates the plot. :param dates: List of the interval of dates to be analyzed (i.e. ['1980-01', '2020-12']). :param time_step: time step of the data (i.e. '1m', '2m', '5m', ...). :return: None -- The function save the plot in a file and does not return a value. """ # Saving plot data figure.savefig(f"../plot/exact_distributions_covariance/{function_name}" + f"_{dates[0]}_{dates[1]}_step_{time_step}.png") print("Plot Saved") print()
def TreeDoubleClick(self, event): try: item=self.selection()[0] item2 = self.identify_row(event.y) if(item != item2): #user double clicked on an item which is not currently selected return except IndexError: return script_name = self.item(item, "text") if self.btestmode: aapl_data = pd.read_csv("E:\\python_projects\\TestData\\daily_MSFT.csv") else: try: aapl_data, aapl_meta_data = self.ts.get_daily(symbol=script_name) # Not sure if we need the following line -- commenting for time being # aapl_sma is a df, aapl_meta_sma also a dict aapl_sma, aapl_meta_sma = self.ti.get_sma(symbol=script_name) except ValueError as error: msgbx.showerror("Alpha Vantage error", error) return # get users price & date dict_curr_row = self.item(script_name) purchase_price = dict_curr_row['values'][1] purchase_date = dict_curr_row['values'][2] # Visualization f_temp=Figure(figsize=(15, 6), dpi=80, facecolor='w', edgecolor='k') plt.clf() if(self.btestmode): # aapl_data['close'].plot(title=script_name) plt.plot(aapl_data['close'], label='Stock price') else: #aapl_data['4. close'].plot(title=script_name) plt.plot(aapl_data['4. close'], label='Stock price') plt.plot(aapl_sma['SMA'], label='SMA') plt.title(script_name) plt.xlabel('Date') plt.ylabel('Price') if ((purchase_date != '') and (purchase_price != '')): plt.annotate('Your price point', (mdates.datestr2num(purchase_date), float(purchase_price)), xytext=(15,15), textcoords='offset points', arrowprops=dict(arrowstyle='-|>')) plt.axhline(float(purchase_price), color='y') # will draw a horizontal line at purchase price plt.tight_layout() plt.legend(loc='upper left') plt.grid() plt.show()
def _( figure: Figure, scale: str = "down", inherit_font: bool = True, tight_layout: bool = True, bbox_inches: str = None, ) -> SVGContentConfiguration: if tight_layout: figure.tight_layout() fig_size = figure.get_size_inches() with io.StringIO() as str_io: figure.savefig(str_io, format="svg", transparent=True, bbox_inches=bbox_inches) svg = str_io.getvalue() return SVGContentConfiguration( data=clean_svg( svg, scale=scale, width=fig_size[0], height=fig_size[1], inherit_font=inherit_font, ) )
def draw_network(network: NetworkType, color=('lightskyblue', 'limegreen', 'goldenrod'), shape=('s', 'o', '^'), fig: plt.Figure = None, save_to=None, **kwargs): nodes = network.nodes.keys() nodes_id = {i: i for i, node in network.nodes.items()} arcs = [(i, j) for i in nodes for j in nodes if i != j] g = nx.DiGraph() g.add_nodes_from(nodes) g.add_edges_from(arcs) if not fig: fig = plt.figure() pos = {i: (network.nodes[i].pos_x, network.nodes[i].pos_y) for i in nodes} nx.draw(g, pos=pos, nodelist=network.depots, arrows=False, node_color=color[0], node_shape=shape[0], labels=nodes_id, **kwargs) nx.draw(g, pos=pos, nodelist=network.customers, arrows=False, node_color=color[1], node_shape=shape[1], labels=nodes_id, **kwargs) nx.draw(g, pos=pos, nodelist=network.charging_stations, arrows=False, node_color=color[2], node_shape=shape[2], labels=nodes_id, **kwargs) if save_to: fig.savefig(save_to) return fig, g
def _plot_save_helper(self, figure: plt.Figure, **kwargs: t.Any): # Get the name of the calling function, look up an entry in the PLOT_FILENAMES dictionary, # or, if unavailable, set the fileneme to the name of the plotting function. caller: str = inspect.stack()[1][3] filename: str = (self.PLOT_FILENAMES[caller] if caller in self.PLOT_FILENAMES else caller.split("plot_")[-1]) add_to_title = None if "add_to_title" in kwargs: add_to_title = kwargs.get("add_to_title", "") if not isinstance(add_to_title, str): add_to_title = str(add_to_title) elif self._global_add_to_title is not None: add_to_title = self._global_add_to_title if add_to_title: title = "{} | {}".format(figure._suptitle.get_text(), add_to_title) figure._suptitle.set_text(title) if "add_to_filename" in kwargs: filename = "{}{}".format(filename, kwargs.get("add_to_filename")) elif self._global_add_to_filename is not None: filename = "{}{}".format(filename, self._global_add_to_filename) if self._save_png: figure.savefig( (self.save_path / filename).with_suffix(".png"), dpi=self._screen_dpi, bbox_inches="tight", ) if self._save_pdf: figure.savefig( (self.save_path / filename).with_suffix(".pdf"), dpi=self._print_dpi, bbox_inches="tight", )
def save_plot(figure: plt.Figure, function_name: str, dates: List[str], time_step: str, window: str) -> None: """Saves plot in png files. Saves the plot generated in the functions of the local_normalization_analysis module in png files. :param figure: figure object that is going to be save. :param function_name: name of the function that generates the plot. :param dates: List of the interval of dates to be analyzed (i.e. ['1980-01', '2020-12']). :param time_step: time step of the data (i.e. '1m', '2m', '5m', ...). :param window: window time to compute the volatility (i.e. '60'). :return: None -- The function save the plot in a file and does not return a value. """ # Saving plot data figure.savefig(f'../plot/local_normalization/{function_name}_{dates[0]}' + f'_{dates[1]}_step_{time_step}_win_{window}.png') print('Plot Saved') print()
def export( fig: plt.Figure, filename: PathType, target_dir: PathType = "plots/", file_formats: Tuple[str, ...] = (".pdf", ".png"), save_as_tikz: bool = False, close_figure: bool = False, ) -> None: """ Convenience function for saving a matplotlib figure. :param fig: A matplotlib figure. :param filename: Filename of the plot without .pdf suffix. :param file_formats: Tuple of file formats specifying the format figure will be saved as. :param target_dir: Directory where the plot will be saved in. Default is './plots/'. :param save_as_tikz: Save the plot also as raw tikz tex document. :param close_figure: Whether to close the figure after saving it. Default is False :return: None """ os.makedirs(target_dir, exist_ok=True) for file_format in file_formats: fig.savefig(os.path.join(target_dir, f"{filename}{file_format}"), bbox_inches="tight") if save_as_tikz: save_figure_as_tikz_tex_file(fig=fig, target_path=os.path.join( target_dir, f"{filename}_tikz.tex")) if close_figure: plt.close(fig) fig.clf()
def prepare_axis(fig: plt.Figure, plot_mode: PlotMode = PlotMode.xy, subplot_arg: int = 111) -> plt.Axes: """ prepares an axis according to the plot mode (for trajectory plotting) :param fig: matplotlib figure object :param plot_mode: PlotMode :param subplot_arg: optional if using subplots - the subplot id (e.g. '122') :return: the matplotlib axis """ if plot_mode == PlotMode.xyz: ax = fig.add_subplot(subplot_arg, projection="3d") else: ax = fig.add_subplot(subplot_arg) ax.axis("equal") if plot_mode in {PlotMode.xy, PlotMode.xz, PlotMode.xyz}: xlabel = "$x$ (m)" elif plot_mode in {PlotMode.yz, PlotMode.yx}: xlabel = "$y$ (m)" else: xlabel = "$z$ (m)" if plot_mode in {PlotMode.xy, PlotMode.zy, PlotMode.xyz}: ylabel = "$y$ (m)" elif plot_mode in {PlotMode.zx, PlotMode.yx}: ylabel = "$x$ (m)" else: ylabel = "$z$ (m)" ax.set_xlabel(xlabel) ax.set_ylabel(ylabel) if plot_mode == PlotMode.xyz: ax.set_zlabel('$z$ (m)') if SETTINGS.plot_invert_xaxis: plt.gca().invert_xaxis() if SETTINGS.plot_invert_yaxis: plt.gca().invert_yaxis() return ax
def hist_save_plot(function_name: str, figure: plt.Figure, fx_pair: str, year: str, month: str) -> None: """Saves plot in png files. Saves the plot generated in the functions of the hist_data_plot_responses_trade module in png files. :param function_name: name of the function that generates the plot. :param figure: figure object that is going to be save. :param fx_pair: string of the abbreviation of the forex pair to be analyzed (i.e. 'eur_usd'). :param year: string of the year to be analyzed (i.e '2016'). :param month: string of the month to be analyzed (i.e '07'). :return: None -- The function save the plot in a file and does not return a value. """ # Saving plot data if (not os.path.isdir( f'../../hist_plot/responses_trade_{year}/{function_name}/')): try: os.mkdir(f'../../hist_plot/responses_trade_{year}/' + f'{function_name}/') print('Folder to save data created') except FileExistsError: print('Folder exists. The folder was not created') figure.savefig(f'../../hist_plot/responses_trade_{year}' + f'/{function_name}/{function_name}_{year}{month}' + f'_{fx_pair}.png') print('Plot saved') print()
def add_figure(self, figure: plt.Figure, caption: Optional[str] = None): buf = io.BytesIO() figure.set_size_inches(6, 4) figure.set_dpi(300) figure.savefig(buf, format="png") b64url = "data:image/png;base64,%s" % base64.b64encode( buf.getvalue()).decode("utf8") self.__elements.append({"kind": "figure", "url": b64url}) plt.clf()
def ray_plot(fig: Figure, source: Origin, reciever: Station, phases: list = None, position=223): """ Use TauP to make a plot of predicted ray-paths. """ phases = phases or DEFAULT_PHASES ax = fig.add_subplot(position, projection="polar") degrees_dist = locations2degrees(reciever.latitude, reciever.longitude, source.latitude, source.longitude) arrivals = MODEL.get_ray_paths(source_depth_in_km=source.depth / 1000.0, distance_in_degree=degrees_dist, phase_list=phases) arrivals.plot_rays(ax=ax, legend=True, show=False) return fig, ax
def isochrones_subfig( fig_: Figure, x_: np.ndarray, y_: np.ndarray, color_: str = gray_ ) -> Tuple[Axes, Tuple[float, float]]: r"""Generate an isochrones subfig for embedding.""" # Top left isochrones 0 size_zoom_0: Tuple[float, float] = (0.65, 0.55) posn_0: Tuple[float, float] = (0.0, 0.75) axes_0 = fig_.add_axes([*posn_0, *size_zoom_0]) plt.axis("off") n_isochrones = 6 for i_, sf_ in enumerate(np.linspace(0.5, 1.2, n_isochrones)): plt.plot( *(x_, sf_ * y_), "-", color=self.gray_color(i_, n_gray), lw=2.5, ) plt.xlim(0, 1) plt.ylim(0, 1) sf1_ = 1.3 sf2_ = 1.3 arrow_xy_: np.ndarray = np.array([0.2, 0.8]) arrow_dxy_: np.ndarray = np.array([-0.025, 0.15]) motion_xy_: Tuple[float, float] = (0.1, 0.8) motion_angle_ = 23 my_arrow_style = ArrowStyle.Simple( head_length=1 * sf1_, head_width=1 * sf1_, tail_width=0.1 * sf1_ ) axes_0.annotate( "", xy=arrow_xy_, xytext=arrow_xy_ + arrow_dxy_ * sf2_, transform=axes_0.transAxes, arrowprops=dict(arrowstyle=my_arrow_style, color=color_, lw=3), ) plt.text( *motion_xy_, "motion", color=color_, fontsize=16, rotation=motion_angle_, transform=axes_0.transAxes, horizontalalignment="center", verticalalignment="center", ) return (axes_0, posn_0)
def _mpl_figure_to_rgb_img(fig: plt.Figure, height, width): fig.set_dpi(100) fig.set_size_inches(width / 100, height / 100) canvas = fig.canvas canvas.draw() width, height = np.round(fig.get_size_inches() * fig.get_dpi()).astype(int) # image = np.fromstring(fig.canvas.tostring_rgb(), dtype='uint8') img = np.fromstring(canvas.tostring_rgb(), dtype='uint8').reshape(height, width, 3) plt.close(fig) return img
def save_plot( path: str, name: str, fig: plt.Figure, file_formats: Iterable[str] = ("png", "pdf"), timestamp: Optional[dt.datetime] = None, ) -> Generator: """ Context manager that creates a new figure on entry and saves the figure using the specified name, format, and path on exit. Parameters ---------- path : str Path prefix to use in constructing the result path name : str Basename to use in constructing the result path file_formats : iterable of str File extensions with which to save the result. Elements must be accepted by ``plt.savefig`` timestamp : datetime or None, optional If given, draw a watermark with the timestamp at the bottom of the figure Examples -------- >>> fig = plt.plot(np.cos(np.linspace(-np.pi, np.pi))) >>> fig.title("My cool plot") >>> save_plot('example/plots', 'test_plot', fig, 'png'): """ outfiles = [ os.path.join(path, os.extsep.join([name, file_format])) for file_format in file_formats ] if timestamp is not None: fig.tight_layout(rect=(0, 0.05, 1, 1)) # leave space for timestamp _plot_updated_timestamp(timestamp, fig) else: fig.tight_layout() # Make sure the directory exists os.makedirs(path, exist_ok=True) for outfile in outfiles: fig.savefig( outfile, transparent=True, ) plt.close(fig=fig)
def add_axes(fig: Figure, rct: Tuple[float, float, float, float], num: int) -> List[Axes]: """ add axes to figure in a rectangular with several panels vertically. :param fig: figure to add axes. :param rct: lower left point x, lower left point y, width, height. :param num: number of panels. :return: a list of axes. """ axs = [] x0, y0, w, h = rct width = w height = h / num for n in range(num): xax = x0 yax = y0 + h - (n + 1) * height ax = fig.add_axes([xax, yax, width, height]) axs.append(ax) return axs
def _fix_shap_force_figure(fig: plt.Figure) -> plt.Figure: """ Replaces the figure annotation in shap force plots with "absent" if value = 0.0 and "present" if value = 1.0. :param fig: a matplotlib.pyplot.Figure as produced by shap.force_plot. :return: The same fig, modified as described. """ ax = fig.gca() for c in ax.get_children(): if isinstance(c, plt.Text): t = c.get_text() if t.endswith(' = 1.0'): c.set_text(t.replace(' = 1.0', ' present')) elif t.endswith(' = 0.0'): c.set_text(t.replace(' = 0.0', ' absent')) else: pass return fig
def latticeplot(optic, diagnostics, size=None): ymin, ymax = 0, 100 fig = Figure(frameon=False) if size is not None: fig.set_figwidth(size[0]) fig.set_figheight(size[1]) ax = fig.add_subplot(111) drawlattice(ax, optic, diagnostics, [ymin, ymax], .3, checkconf=False) s = cumsum(optic[1, :]) ax.set_xlim(0, s[-1]) ax.set_ylim(ymin, ymax) ax.axis('off') ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) return fig
def __init__(self, parent, *args, **kwargs): wx.Dialog.__init__(self, parent, -1, _("Insert chart"), *args, size=(900, 700), style=wx.RESIZE_BORDER, **kwargs) self.splitter = wx.SplitterWindow(self, -1, style=wx.SP_LIVE_UPDATE) self.splitter.parent = self # Create a CustomTreeCtrl instance self.tree = ChartTree(self.splitter, style=wx.BORDER_SUNKEN) self.figure_panel = FigurePanel(self.splitter) # Dummy figure self.figure = Figure(facecolor='white') ax = self.figure.add_subplot(111) ax.xaxis.set_picker(5) ax.xaxis.name = "xaxis" ax.yaxis.set_picker(5) ax.yaxis.name = "yaxis" plt = ax.plot([(x/10.0)**2 for x in xrange(1000)], picker=5) plt[-1].name = "test" self.figure_panel.update(self.figure) # Split Window self.splitter.SplitVertically(self.tree, self.figure_panel) self.splitter.SetMinimumPaneSize(10) self.splitter.SetSashPosition(400) # Buttons self.button_add = wx.Button(self, wx.ID_ADD) self.button_remove = wx.Button(self, wx.ID_REMOVE) self.button_cancel = wx.Button(self, wx.ID_CANCEL) self.button_ok = wx.Button(self, wx.ID_OK) self.button_add.Bind(wx.EVT_BUTTON, self.OnAdd) self._layout()
class MainWindow(QMainWindow): """ Class of Main Window (top) """ _errMsgWindow = None def __init__(self, parent=None): """ Initialization and set up """ # Base class QMainWindow.__init__(self, parent) # Mantid configuration config = ConfigService.Instance() self._instrument = config["default.instrument"] # Central widget self.centralwidget = QWidget(self) # UI Window (from Qt Designer) self.ui = load_ui(__file__, 'MainWindow.ui', baseinstance=self) mpl_layout = QVBoxLayout() self.ui.graphicsView.setLayout(mpl_layout) self.fig = Figure() self.canvas = FigureCanvas(self.fig) self.ui.mainplot = self.fig.add_subplot(111, projection='mantid') mpl_layout.addWidget(self.canvas) # Do initialize plotting vecx, vecy, xlim, ylim = self.computeMock() self.mainline = self.ui.mainplot.plot(vecx, vecy, 'r-') leftx = [xlim[0], xlim[0]] lefty = [ylim[0], ylim[1]] self.leftslideline = self.ui.mainplot.plot(leftx, lefty, 'b--') rightx = [xlim[1], xlim[1]] righty = [ylim[0], ylim[1]] self.rightslideline = self.ui.mainplot.plot(rightx, righty, 'g--') upperx = [xlim[0], xlim[1]] uppery = [ylim[1], ylim[1]] self.upperslideline = self.ui.mainplot.plot(upperx, uppery, 'b--') lowerx = [xlim[0], xlim[1]] lowery = [ylim[0], ylim[0]] self.lowerslideline = self.ui.mainplot.plot(lowerx, lowery, 'g--') self.canvas.mpl_connect('button_press_event', self.on_mouseDownEvent) # Set up horizontal slide (integer) and string value self._leftSlideValue = 0 self._rightSlideValue = 99 self.ui.horizontalSlider.setRange(0, 100) self.ui.horizontalSlider.setValue(self._leftSlideValue) self.ui.horizontalSlider.setTracking(True) self.ui.horizontalSlider.setTickPosition(QSlider.NoTicks) self.ui.horizontalSlider.valueChanged.connect(self.move_leftSlider) self.ui.horizontalSlider_2.setRange(0, 100) self.ui.horizontalSlider_2.setValue(self._rightSlideValue) self.ui.horizontalSlider_2.setTracking(True) self.ui.horizontalSlider_2.setTickPosition(QSlider.NoTicks) self.ui.horizontalSlider_2.valueChanged.connect(self.move_rightSlider) # self.connect(self.ui.lineEdit_3, QtCore.SIGNAL("textChanged(QString)"), # self.set_startTime) self.ui.lineEdit_3.setValidator(QDoubleValidator(self.ui.lineEdit_3)) self.ui.pushButton_setT0.clicked.connect(self.set_startTime) # self.connect(self.ui.lineEdit_4, QtCore.SIGNAL("textChanged(QString)"), # self.set_stopTime) self.ui.lineEdit_4.setValidator(QDoubleValidator(self.ui.lineEdit_4)) self.ui.pushButton_setTf.clicked.connect(self.set_stopTime) # File loader self.scanEventWorkspaces() self.ui.pushButton_refreshWS.clicked.connect(self.scanEventWorkspaces) self.ui.pushButton_browse.clicked.connect(self.browse_File) self.ui.pushButton_load.clicked.connect(self.load_File) self.ui.pushButton_3.clicked.connect(self.use_existWS) # Set up time self.ui.lineEdit_3.setValidator(QDoubleValidator(self.ui.lineEdit_3)) self.ui.lineEdit_4.setValidator(QDoubleValidator(self.ui.lineEdit_4)) # Filter by time self.ui.pushButton_filterTime.clicked.connect(self.filterByTime) # Filter by log value self.ui.lineEdit_5.setValidator(QDoubleValidator(self.ui.lineEdit_5)) self.ui.lineEdit_6.setValidator(QDoubleValidator(self.ui.lineEdit_6)) self.ui.lineEdit_7.setValidator(QDoubleValidator(self.ui.lineEdit_7)) self.ui.lineEdit_8.setValidator(QDoubleValidator(self.ui.lineEdit_8)) self.ui.lineEdit_9.setValidator(QDoubleValidator(self.ui.lineEdit_9)) self.ui.lineEdit_5.textChanged.connect(self.set_minLogValue) self.ui.lineEdit_6.textChanged.connect(self.set_maxLogValue) dirchangeops = ["Both", "Increase", "Decrease"] self.ui.comboBox_4.addItems(dirchangeops) logboundops = ["Centre", "Left"] self.ui.comboBox_5.addItems(logboundops) self.ui.pushButton_4.clicked.connect(self.plotLogValue) self.ui.pushButton_filterLog.clicked.connect(self.filterByLogValue) # Set up help button self.ui.helpBtn.clicked.connect(self.helpClicked) # Set up vertical slide self._upperSlideValue = 99 self._lowerSlideValue = 0 self.ui.verticalSlider.setRange(0, 100) self.ui.verticalSlider.setValue(self._upperSlideValue) self.ui.verticalSlider.setTracking(True) self.ui.verticalSlider.valueChanged.connect(self.move_upperSlider) self.ui.verticalSlider_2.setRange(0, 100) self.ui.verticalSlider_2.setValue(self._lowerSlideValue) self.ui.verticalSlider_2.setTracking(True) self.ui.verticalSlider_2.valueChanged.connect(self.move_lowerSlider) # Set up for filtering (advanced setup) self._tofcorrection = False self.ui.checkBox_fastLog.setChecked(False) self.ui.checkBox_filterByPulse.setChecked(False) self.ui.checkBox_from1.setChecked(False) self.ui.checkBox_groupWS.setChecked(True) self.ui.comboBox_tofCorr.currentIndexChanged.connect(self.showHideEi) self.ui.pushButton_refreshCorrWSList.clicked.connect(self._searchTableWorkspaces) self.ui.lineEdit_Ei.setValidator(QDoubleValidator(self.ui.lineEdit_Ei)) self.ui.label_Ei.hide() self.ui.lineEdit_Ei.hide() self.ui.label_Ei_2.hide() self.ui.comboBox_corrWS.hide() self.ui.pushButton_refreshCorrWSList.hide() # Set up for workspaces self._dataWS = None self._sampleLogNames = [] self._sampleLog = None # Side information self.ui.label_mean.hide() self.ui.label_meanvalue.hide() self.ui.label_avg.hide() self.ui.label_timeAvgValue.hide() self.ui.label_freq.hide() self.ui.label_freqValue.hide() self.ui.label_logname.hide() self.ui.label_lognamevalue.hide() self.ui.label_logsize.hide() self.ui.label_logsizevalue.hide() # Default self._defaultdir = os.getcwd() # register startup mantid.UsageService.registerFeatureUsage("Interface", "EventFilter", False) def on_mouseDownEvent(self, event): """ Respond to pick up a value with mouse down event """ x = event.xdata y = event.ydata if x is not None and y is not None: msg = "You've clicked on a bar with coords:\n %f, %f" % (x, y) QMessageBox.information(self, "Click!", msg) def computeMock(self): """ Compute vecx and vecy as mocking """ x0 = 0. xf = 1. dx = 0.1 vecx = [] vecy = [] x = x0 while x < xf: y = 0.0 vecx.append(x) vecy.append(y) x += dx xlim = [x0, xf] ylim = [-1., 1] return (vecx, vecy, xlim, ylim) def move_leftSlider(self): """ Re-setup left range line in figure. Triggered by a change in Qt Widget. NO EVENT is required. """ newx = self.ui.horizontalSlider.value() if newx <= self._rightSlideValue and newx != self._leftSlideValue: # Allowed value: move the value bar self._leftSlideValue = newx # Move the vertical line xlim = self.ui.mainplot.get_xlim() newx = xlim[0] + newx*(xlim[1] - xlim[0])*0.01 leftx = [newx, newx] lefty = self.ui.mainplot.get_ylim() setp(self.leftslideline, xdata=leftx, ydata=lefty) self.canvas.draw() # Change value self.ui.lineEdit_3.setText(str(newx)) else: # Reset the value to original value self.ui.horizontalSlider.setValue(self._leftSlideValue) def set_startTime(self): """ Set the starting time and left slide bar """ inps = str(self.ui.lineEdit_3.text()) info_msg = "Starting time = %s" % (inps) Logger("Filter_Events").information(info_msg) xlim = self.ui.mainplot.get_xlim() if inps == "": # Empty. Use default newtime0 = xlim[0] else: newtime0 = float(inps) # Convert to integer slide value ileftvalue = int((newtime0-xlim[0])/(xlim[1] - xlim[0])*100) debug_msg = "iLeftSlide = %s" % str(ileftvalue) Logger("Filter_Events").debug(debug_msg) # Skip if same as origina if ileftvalue == self._leftSlideValue: return # Set the value if out of range resetT = True if ileftvalue < 0: # Minimum value as 0 ileftvalue = 0 elif ileftvalue > self._rightSlideValue: # Maximum value as right slide value ileftvalue = self._rightSlideValue else: resetT = False if resetT is True: newtime0 = xlim[0] + ileftvalue*(xlim[1]-xlim[0])*0.01 info_msg = 'Corrected iLeftSlide = {} (vs. right = {})'.format(ileftvalue, self._rightSlideValue) Logger("Filter_Events").information(info_msg) # Move the slide bar (left) self._leftSlideValue = ileftvalue # Move the vertical line leftx = [newtime0, newtime0] lefty = self.ui.mainplot.get_ylim() setp(self.leftslideline, xdata=leftx, ydata=lefty) self.canvas.draw() # Set the value to left slider self.ui.horizontalSlider.setValue(self._leftSlideValue) # Reset the value of line edit if resetT is True: self.ui.lineEdit_3.setText(str(newtime0)) def move_rightSlider(self): """ Re-setup left range line in figure. Triggered by a change in Qt Widget. NO EVENT is required. """ newx = self.ui.horizontalSlider_2.value() if newx >= self._leftSlideValue and newx != self._rightSlideValue: # Allowed value: move the value bar self._rightSlideValue = newx xlim = self.ui.mainplot.get_xlim() newx = xlim[0] + newx*(xlim[1] - xlim[0])*0.01 leftx = [newx, newx] lefty = self.ui.mainplot.get_ylim() setp(self.rightslideline, xdata=leftx, ydata=lefty) self.canvas.draw() # Change value self.ui.lineEdit_4.setText(str(newx)) else: # Reset the value self.ui.horizontalSlider_2.setValue(self._rightSlideValue) def set_stopTime(self): """ Set the starting time and left slide bar """ inps = str(self.ui.lineEdit_4.text()) Logger("Filter_Events").information('Stopping time = {}'.format(inps)) xlim = self.ui.mainplot.get_xlim() if inps == "": # Empty. Use default newtimef = xlim[1] else: # Parse newtimef = float(inps) # Convert to integer slide value irightvalue = int((newtimef-xlim[0])/(xlim[1] - xlim[0])*100) Logger("Filter_Events").information('iRightSlide = {}'.format(irightvalue)) # Return if no change if irightvalue == self._rightSlideValue: return # Correct value resetT = True if irightvalue > 100: irightvalue = 100 elif irightvalue < self._leftSlideValue: irightvalue = self._leftSlideValue else: resetT = False if resetT is True: newtimef = xlim[0] + irightvalue*(xlim[1]-xlim[0])*0.01 # Move the slide bar (right) self._rightSlideValue = irightvalue # Move the vertical line rightx = [newtimef, newtimef] righty = self.ui.mainplot.get_ylim() setp(self.rightslideline, xdata=rightx, ydata=righty) self.canvas.draw() # Set the value to left slider self.ui.horizontalSlider_2.setValue(self._rightSlideValue) # Reset to line edit if resetT: self.ui.lineEdit_4.setText(str(newtimef)) def move_lowerSlider(self): """ Re-setup upper range line in figure. Triggered by a change in Qt Widget. NO EVENT is required. """ inewy = self.ui.verticalSlider_2.value() debug_msg = 'LowerSlFider is set with value {} vs. class variable {}'.format(inewy, self._lowerSlideValue) Logger("Filter_Events").debug(debug_msg) # Return with no change if inewy == self._lowerSlideValue: # No change return if inewy >= self._upperSlideValue: # Out of upper range inewy = self._upperSlideValue - 1 if inewy == 0 and self._lowerSlideValue < 0: setLineEdit = False else: setLineEdit = True # Move the lower vertical bar ylim = self.ui.mainplot.get_ylim() newy = ylim[0] + inewy*(ylim[1] - ylim[0])*0.01 lowerx = self.ui.mainplot.get_xlim() lowery = [newy, newy] setp(self.lowerslideline, xdata=lowerx, ydata=lowery) self.canvas.draw() # Set line edit input if setLineEdit is True: # Change value to line edit (5) self.ui.lineEdit_5.setText(str(newy)) # Reset the class variable self._lowerSlideValue = inewy def set_minLogValue(self): """ Set the starting time and left slide bar """ debug_msg = 'Minimum Log Value = {}'.format(self.ui.lineEdit_5.text()) Logger("Filter_Events").debug(debug_msg) ylim = self.ui.mainplot.get_ylim() if str(self.ui.lineEdit_5.text()) == "": # Empty. Default to minY newminY = ylim[0] else: # Non empty. Parse newminY = float(self.ui.lineEdit_5.text()) # Convert to integer slide value iminlogval = int((newminY-ylim[0])/(ylim[1] - ylim[0])*100) Logger("Filter_Events").debug('ilowerSlide = {}'.format(iminlogval)) # Return if no change if iminlogval == self._lowerSlideValue: return # Set value if out of range resetL = True if iminlogval >= self._upperSlideValue: iminlogval = self._upperSlideValue - 1 else: resetL = False if resetL is True: newminY = ylim[0] + iminlogval * (ylim[1]-ylim[0]) * 0.01 # Move the vertical line lowerx = self.ui.mainplot.get_xlim() lowery = [newminY, newminY] setp(self.lowerslideline, xdata=lowerx, ydata=lowery) self.canvas.draw() # Move the slide bar (lower) self._lowerSlideValue = iminlogval debug_msg = 'LineEdit5 set slide to {}'.format(self._lowerSlideValue) Logger("Filter_Events").debug(debug_msg) self.ui.verticalSlider_2.setValue(self._lowerSlideValue) # Reset line Edit if using default if resetL is True: self.ui.lineEdit_5.setText(str(newminY)) def move_upperSlider(self): """ Re-setup upper range line in figure. Triggered by a change in Qt Widget. NO EVENT is required. """ inewy = self.ui.verticalSlider.value() # Return w/o change if inewy == self._upperSlideValue: return # Set to boundary value if inewy <= self._lowerSlideValue: inewy = self._lowerSlideValue + 1 # Reset line editor? if inewy == 100 and self._upperSlideValue > 100: setLineEdit = False else: setLineEdit = True # Move the upper value bar: upperx and uppery are # real value (float but not (0,100)) of the figure ylim = self.ui.mainplot.get_ylim() newy = ylim[0] + inewy*(ylim[1] - ylim[0])*0.01 upperx = self.ui.mainplot.get_xlim() uppery = [newy, newy] setp(self.upperslideline, xdata=upperx, ydata=uppery) self.canvas.draw() # Change value if setLineEdit is True: self.ui.lineEdit_6.setText(str(newy)) self._upperSlideValue = inewy def set_maxLogValue(self): """ Set maximum log value from line-edit """ inps = str(self.ui.lineEdit_6.text()) debug_msg = 'Maximum Log Value = {}'.format(inps) Logger("Filter_Events").debug(debug_msg) ylim = self.ui.mainplot.get_ylim() if inps == "": # Empty. Default to minY newmaxY = ylim[1] else: # Parse newmaxY = float(inps) # Convert to integer slide value imaxlogval = int((newmaxY-ylim[0])/(ylim[1] - ylim[0])*100) debug_msg = 'iUpperSlide = {}'.format(imaxlogval) Logger("Filter_Events").debug(debug_msg) # Return if no change if imaxlogval == self._upperSlideValue: return # Set to default if out of range resetL = True # if imaxlogval >= 100: # imaxlogval = 100 if imaxlogval < self._lowerSlideValue: imaxlogval = self._lowerSlideValue + 1 else: resetL = False # Set newmaxY if necessary if resetL is True: newmaxY = ylim[0] + imaxlogval * (ylim[1] - ylim[0]) * 0.01 # Move the vertical line upperx = self.ui.mainplot.get_xlim() uppery = [newmaxY, newmaxY] setp(self.upperslideline, xdata=upperx, ydata=uppery) self.canvas.draw() # Set the value to upper slider self._upperSlideValue = imaxlogval self.ui.verticalSlider.setValue(self._upperSlideValue) # Set the value to editor if necessary if resetL is True: self.ui.lineEdit_6.setText(str(newmaxY)) def browse_File(self): """ Open a file dialog to get file """ filename = QFileDialog.getOpenFileName(self, 'Input File Dialog', self._defaultdir, "Data (*.nxs *.dat);;All files (*)") if isinstance(filename, tuple): filename = filename[0] self.ui.lineEdit.setText(filename) Logger("Filter_Events").information('Selected file: "{}"'.format(filename)) def load_File(self): """ Load the file by file name or run number """ # Get file name from line editor filename = str(self.ui.lineEdit.text()) dataws = self._loadFile(str(filename)) if dataws is None: error_msg = 'Unable to locate run {} in default directory {}.'.format(filename, self._defaultdir) Logger("Filter_Events").error(error_msg) self._setErrorMsg(error_msg) else: self._importDataWorkspace(dataws) self._defaultdir = os.path.dirname(str(filename)) # Reset GUI self._resetGUI(resetfilerun=False) def use_existWS(self): """ Set up workspace to an existing one """ wsname = str(self.ui.comboBox.currentText()) try: dataws = AnalysisDataService.retrieve(wsname) self._importDataWorkspace(dataws) except KeyError: pass # Reset GUI self._resetGUI(resetfilerun=True) def plotLogValue(self): """ Plot log value """ # Get log value logname = str(self.ui.comboBox_2.currentText()) if len(logname) == 0: # return due to the empty one is chozen return samplelog = self._dataWS.getRun().getProperty(logname) vectimes = samplelog.times vecvalue = samplelog.value # check if len(vectimes) == 0: error_msg = "Empty log!" Logger("Filter_Events").error(error_msg) # Convert absolute time to relative time in seconds t0 = self._dataWS.getRun().getProperty("proton_charge").times[0] # append 1 more log if original log only has 1 value tf = self._dataWS.getRun().getProperty("proton_charge").times[-1] vectimes = numpy.append(vectimes, tf) vecvalue = numpy.append(vecvalue, vecvalue[-1]) vecreltimes = (vectimes - t0) / numpy.timedelta64(1, 's') # Set to plot xlim = [vecreltimes.min(), vecreltimes.max()] ylim = [vecvalue.min(), vecvalue.max()] self.ui.mainplot.set_xlim(xlim[0], xlim[1]) self.ui.mainplot.set_ylim(ylim[0], ylim[1]) setp(self.mainline, xdata=vecreltimes, ydata=vecvalue) samunit = samplelog.units if len(samunit) == 0: ylabel = logname else: ylabel = "%s (%s)" % (logname, samunit) self.ui.mainplot.set_ylabel(ylabel, fontsize=13) # assume that all logs are on almost same X-range. Only Y need to be reset setp(self.leftslideline, ydata=ylim) setp(self.rightslideline, ydata=ylim) # reset the log value limit as previous one does not make any sense setp(self.lowerslideline, xdata=xlim, ydata=[ylim[0], ylim[0]]) self._lowerSlideValue = 0 self.ui.verticalSlider_2.setValue(self._lowerSlideValue) self.ui.lineEdit_5.setText("") setp(self.upperslideline, xdata=xlim, ydata=[ylim[1], ylim[1]]) self._upperSlideValue = 100 self.ui.verticalSlider.setValue(self._upperSlideValue) self.ui.lineEdit_6.setText("") self.canvas.draw() # Load property's statistic and give suggestion on parallel and fast log timeavg = samplelog.timeAverageValue() numentries = samplelog.size() stat = samplelog.getStatistics() duration = stat.duration mean = stat.mean freq = float(numentries)/float(duration) self.ui.label_mean.show() self.ui.label_meanvalue.show() self.ui.label_avg.show() self.ui.label_timeAvgValue.show() self.ui.label_freq.show() self.ui.label_freqValue.show() self.ui.label_logname.show() self.ui.label_lognamevalue.show() self.ui.label_logsize.show() self.ui.label_logsizevalue.show() self.ui.label_meanvalue.setText("%.5e" % (mean)) self.ui.label_timeAvgValue.setText("%.5e" % (timeavg)) self.ui.label_freqValue.setText("%.5e" % (freq)) self.ui.label_lognamevalue.setText(logname) self.ui.label_logsizevalue.setText(str(numentries)) # Set suggested processing scheme if numentries > HUGE_FAST: self.ui.checkBox_fastLog.setCheckState(True) if numentries > HUGE_PARALLEL: self.ui.checkBox_doParallel.setCheckState(True) else: self.ui.checkBox_doParallel.setCheckState(False) else: self.ui.checkBox_fastLog.setCheckState(False) self.ui.checkBox_doParallel.setCheckState(False) return def _importDataWorkspace(self, dataws): """ Import data workspace for filtering """ if dataws is None: return # Plot time counts errmsg = self._plotTimeCounts(dataws) if errmsg is not None: errmsg = 'Workspace {} has invalid sample logs for splitting. Loading \ failure! \n{}\n'.format(dataws, errmsg) self._setErrorMsg(errmsg) return False # Import log self._sampleLogNames = [""] run = dataws.getRun() plist = run.getProperties() for p in plist: try: times = p.times if len(times) > 1 and numpy.isreal(p.value[0]): self._sampleLogNames.append(p.name) # This is here for FloatArrayProperty. If a log value is of this type it does not have times except AttributeError: pass # ENDFOR(p) # Set up sample log self.ui.comboBox_2.clear() self.ui.comboBox_2.addItems(self._sampleLogNames) # Side information self.ui.label_mean.hide() self.ui.label_meanvalue.hide() self.ui.label_avg.hide() self.ui.label_timeAvgValue.hide() self.ui.label_freq.hide() self.ui.label_freqValue.hide() # Hide 'log name' above the graphic view self.ui.label_logname.hide() self.ui.label_lognamevalue.hide() # Set dataws to class variable self._dataWS = dataws return True def scanEventWorkspaces(self): """ """ wsnames = AnalysisDataService.getObjectNames() eventwsnames = [] for wsname in wsnames: wksp = AnalysisDataService.retrieve(wsname) if wksp.__class__.__name__.count("Event") == 1: eventwsnames.append(wsname) # ENDFOR if len(eventwsnames) > 0: self.ui.comboBox.clear() self.ui.comboBox.addItems(eventwsnames) def _loadFile(self, filename): """ Load file or run File will be loaded to a workspace shown in MantidPlot """ config = ConfigService # Check input file name and output workspace name if filename.isdigit() is True: # Construct a file name from run number runnumber = int(filename) if runnumber <= 0: error_msg = 'Run number cannot be less or equal to zero. User gives {}.'.format(filename) Logger("Filter_Events").error(error_msg) return None else: ishort = config.getInstrument(self._instrument).shortName() filename = '{}_{}'.format(ishort, filename) wsname = filename + "_event" elif filename.count(".") > 0: # A proper file name wsname = os.path.splitext(os.path.split(filename)[1])[0] elif filename.count("_") == 1: # A short one as instrument_runnumber iname = filename.split("_")[0] str_runnumber = filename.split("_")[1] if str_runnumber.isdigit() is True and int(str_runnumber) > 0: # Accepted format ishort = config.getInstrument(iname).shortName() wsname = '{}_{}_event'.format(ishort, str_runnumber) else: # Non-supported error_msg = 'File name / run number in such format {} is not supported.'.format(filename) Logger("Filter_Events").error(error_msg) return None else: # Unsupported format error_msg = 'File name / run number in such format {} is not supported.'.format(filename) Logger("Filter_Events").error(error_msg) return None # Load try: ws = api.Load(Filename=filename, OutputWorkspace=wsname) except RuntimeError as e: ws = None return str(e) return ws def _plotTimeCounts(self, wksp): """ Plot time/counts """ import datetime # Rebin events by pulse time try: # Get run start and run stop if wksp.getRun().hasProperty("run_start"): runstart = wksp.getRun().getProperty("run_start").value else: runstart = wksp.getRun().getProperty("proton_charge").times[0] runstop = wksp.getRun().getProperty("proton_charge").times[-1] runstart = str(runstart).split(".")[0].strip() runstop = str(runstop).split(".")[0].strip() t0 = datetime.datetime.strptime(runstart, "%Y-%m-%dT%H:%M:%S") tf = datetime.datetime.strptime(runstop, "%Y-%m-%dT%H:%M:%S") # Calculate dt = tf-t0 timeduration = dt.days*3600*24 + dt.seconds timeres = float(timeduration)/MAXTIMEBINSIZE if timeres < 1.0: timeres = 1.0 sumwsname = '_Summed_{}'.format(wksp) if AnalysisDataService.doesExist(sumwsname) is False: sumws = api.SumSpectra(InputWorkspace=wksp, OutputWorkspace=sumwsname) sumws = api.RebinByPulseTimes(InputWorkspace=sumws, OutputWorkspace=sumwsname, Params='{}'.format(timeres)) sumws = api.ConvertToPointData(InputWorkspace=sumws, OutputWorkspace=sumwsname) else: sumws = AnalysisDataService.retrieve(sumwsname) except RuntimeError as e: return str(e) vecx = sumws.readX(0) vecy = sumws.readY(0) xmin = min(vecx) xmax = max(vecx) ymin = min(vecy) ymax = max(vecy) # Reset graph self.ui.mainplot.set_xlim(xmin, xmax) self.ui.mainplot.set_ylim(ymin, ymax) self.ui.mainplot.set_xlabel('Time (seconds)', fontsize=13) self.ui.mainplot.set_ylabel('Counts', fontsize=13) # Set up main line setp(self.mainline, xdata=vecx, ydata=vecy) # Reset slide newslidery = [min(vecy), max(vecy)] newleftx = xmin + (xmax-xmin)*self._leftSlideValue*0.01 setp(self.leftslideline, xdata=[newleftx, newleftx], ydata=newslidery) newrightx = xmin + (xmax-xmin)*self._rightSlideValue*0.01 setp(self.rightslideline, xdata=[newrightx, newrightx], ydata=newslidery) self.canvas.draw() def filterByTime(self): """ Filter by time """ # Generate event filters kwargs = {} if self.ui.lineEdit_3.text() != "": rel_starttime = float(self.ui.lineEdit_3.text()) kwargs["StartTime"] = str(rel_starttime) if self.ui.lineEdit_4.text() != "": rel_stoptime = float(self.ui.lineEdit_4.text()) kwargs["StopTime"] = str(rel_stoptime) if self.ui.lineEdit_timeInterval.text() != "": interval = float(self.ui.lineEdit_timeInterval.text()) kwargs["TimeInterval"] = interval splitwsname = str(self._dataWS) + "_splitters" splitinfowsname = str(self._dataWS) + "_info" title = str(self.ui.lineEdit_title.text()) fastLog = self.ui.checkBox_fastLog.isChecked() splitws, infows = api.GenerateEventsFilter(InputWorkspace=self._dataWS, UnitOfTime="Seconds", TitleOfSplitters=title, OutputWorkspace=splitwsname, FastLog=fastLog, InformationWorkspace=splitinfowsname, **kwargs) self.splitWksp(splitws, infows) def filterByLogValue(self): """ Filter by log value """ # Generate event filter kwargs = {} samplelog = str(self.ui.comboBox_2.currentText()) if len(samplelog) == 0: error_msg = "No sample log is selected!" Logger("Filter_Events").error(error_msg) return if self.ui.lineEdit_3.text() != "": rel_starttime = float(self.ui.lineEdit_3.text()) kwargs["StartTime"] = str(rel_starttime) if self.ui.lineEdit_4.text() != "": rel_stoptime = float(self.ui.lineEdit_4.text()) kwargs["StopTime"] = str(rel_stoptime) if self.ui.lineEdit_5.text() != "": minlogvalue = float(self.ui.lineEdit_5.text()) kwargs["MinimumLogValue"] = minlogvalue if self.ui.lineEdit_6.text() != "": maxlogvalue = float(self.ui.lineEdit_6.text()) kwargs["MaximumLogValue"] = maxlogvalue if self.ui.lineEdit_7.text() != "": logvalueintv = float(self.ui.lineEdit_7.text()) kwargs["LogValueInterval"] = logvalueintv logvalchangedir = str(self.ui.comboBox_4.currentText()) kwargs["FilterLogValueByChangingDirection"] = logvalchangedir if self.ui.lineEdit_9.text() != "": logvalueintv = float(self.ui.lineEdit_9.text()) kwargs["TimeTolerance"] = logvalueintv logboundtype = str(self.ui.comboBox_5.currentText()) kwargs["LogBoundary"] = logboundtype if self.ui.lineEdit_8.text() != "": logvaluetol = float(self.ui.lineEdit_8.text()) kwargs["LogValueTolerance"] = logvaluetol splitwsname = str(self._dataWS) + "_splitters" splitinfowsname = str(self._dataWS) + "_info" fastLog = self.ui.checkBox_fastLog.isChecked() title = str(self.ui.lineEdit_title.text()) splitws, infows = api.GenerateEventsFilter(InputWorkspace=self._dataWS, UnitOfTime="Seconds", TitleOfSplitters=title, OutputWorkspace=splitwsname, LogName=samplelog, FastLog=fastLog, InformationWorkspace=splitinfowsname, **kwargs) try: self.splitWksp(splitws, infows) except RuntimeError as e: self._setErrorMsg("Splitting Failed!\n %s" % (str(e))) def splitWksp(self, splitws, infows): """ Run FilterEvents """ dogroupws = self.ui.checkBox_groupWS.isChecked() filterbypulse = self.ui.checkBox_filterByPulse.isChecked() startfrom1 = self.ui.checkBox_from1.isChecked() splitsamplelog = self.ui.checkBox_splitLog.isChecked() corr2sample = str(self.ui.comboBox_tofCorr.currentText()) how2skip = str(self.ui.comboBox_skipSpectrum.currentText()) kwargs = {} if corr2sample == "Direct": ei = float(self.ui.lineEdit_Ei.text()) kwargs["IncidentEnergy"] = ei elif corr2sample == "Customized": corrws = str(self.ui.comboBox_corrWS.currentText()) kwargs["DetectorTOFCorrectionWorkspace"] = corrws # Output workspace name outbasewsname = str(self.ui.lineEdit_outwsname.text()) if len(outbasewsname) == 0: outbasewsname = "tempsplitted" self.ui.lineEdit_outwsname.setText(outbasewsname) api.FilterEvents(InputWorkspace=self._dataWS, SplitterWorkspace=splitws, InformationWorkspace=infows, OutputWorkspaceBaseName=outbasewsname, GroupWorkspaces=dogroupws, FilterByPulseTime=filterbypulse, CorrectionToSample=corr2sample, SpectrumWithoutDetector=how2skip, SplitSampleLogs=splitsamplelog, OutputWorkspaceIndexedFrom1=startfrom1, OutputTOFCorrectionWorkspace='TOFCorrTable', **kwargs) def showHideEi(self): """ """ corrtype = str(self.ui.comboBox_tofCorr.currentText()) # Incident energy if corrtype == "Direct": self.ui.label_Ei.show() self.ui.lineEdit_Ei.show() else: self.ui.label_Ei.hide() self.ui.lineEdit_Ei.hide() # Workspace if corrtype == "Customized": self.ui.label_Ei_2.show() self.ui.comboBox_corrWS.show() self.ui.pushButton_refreshCorrWSList.show() # Search for table workspace self._searchTableWorkspaces() else: self.ui.label_Ei_2.hide() self.ui.comboBox_corrWS.hide() self.ui.pushButton_refreshCorrWSList.hide() def _searchTableWorkspaces(self): """ Search table workspaces and add to 'comboBox_corrWS' """ wsnames = AnalysisDataService.getObjectNames() tablewsnames = [] for wsname in wsnames: wksp = AnalysisDataService.retrieve(wsname) if isinstance(wksp, mantid.api.ITableWorkspace): tablewsnames.append(wsname) # ENDFOR self.ui.comboBox_corrWS.clear() if len(tablewsnames) > 0: self.ui.comboBox_corrWS.addItems(tablewsnames) def _setErrorMsg(self, errmsg): """ Clear error message """ self._errMsgWindow = QMessageBox() self._errMsgWindow.setIcon(QMessageBox.Critical) self._errMsgWindow.setWindowTitle('Error') self._errMsgWindow.setStandardButtons(QMessageBox.Ok) self._errMsgWindow.setText(errmsg) result = self._errMsgWindow.exec_() return result def helpClicked(self): try: from pymantidplot.proxies import showCustomInterfaceHelp showCustomInterfaceHelp("Filter Events") except ImportError: url = ("http://docs.mantidproject.org/nightly/interfaces/{}.html" "".format("Filter Events")) QDesktopServices.openUrl(QUrl(url)) def _resetGUI(self, resetfilerun=False): """ Reset GUI including all text edits and etc. """ if resetfilerun is True: self.ui.lineEdit.clear() # Plot related self.ui.lineEdit_3.clear() self.ui.lineEdit_4.clear() self.ui.horizontalSlider.setValue(0) self.ui.horizontalSlider_2.setValue(100) self.ui.lineEdit_outwsname.clear() self.ui.lineEdit_title.clear() # Filter by log value self.ui.lineEdit_5.clear() self.ui.lineEdit_6.clear() self.ui.verticalSlider_2.setValue(0) self.ui.verticalSlider.setValue(100) ylim = self.ui.mainplot.get_ylim() miny = ylim[0] maxy = ylim[1] xlim = self.ui.mainplot.get_xlim() setp(self.lowerslideline, xdata=xlim, ydata=[miny, miny]) setp(self.upperslideline, xdata=xlim, ydata=[maxy, maxy]) self.ui.lineEdit_7.clear() self.ui.lineEdit_8.clear() self.ui.lineEdit_9.clear() # Filter by time self.ui.lineEdit_timeInterval.clear() # Advanced setup self.ui.comboBox_tofCorr.setCurrentIndex(0) self.ui.lineEdit_Ei.clear() self.ui.checkBox_fastLog.setCheckState(False) self.ui.checkBox_doParallel.setCheckState(False) self.ui.comboBox_skipSpectrum.setCurrentIndex(0) self.ui.checkBox_filterByPulse.setCheckState(False) self.ui.checkBox_from1.setCheckState(False) self.ui.checkBox_groupWS.setCheckState(True) self.ui.checkBox_splitLog.setCheckState(False) self.canvas.draw()
class HistoricalViewerApp: line_styles = ["solid"] colors = [ (0.0, 0.0, 1.0, 1.0), #Blue (1.0, 0.0, 0.0, 1.0), #Red (0.0, 1.0, 0.0, 1.0), #Green (1.0, 1.0, 0.0, 1.0) ] def __init__(self, width, height): self.path = config.find_options("general.cfg")['database'] self.descriptors = config.find_graphs("graphs.cfg") self.data = {} self.collections = {} self.nav_collections = {} self.color_map = {} self.connection = sql.connect(self.path, detect_types=(sql.PARSE_COLNAMES|sql.PARSE_DECLTYPES)) self.root = Tk.Tk() self.root.wm_title("Historical Data Viewer") self.intervals = self.connection.execute("SELECT * FROM intervals ORDER BY start;").fetchall() self.intervals = list(reversed(self.intervals)) #Grid layout: # Col 0 Col 1 # +------------+------+ # Row 0 | | ITVL | # | ZOOM | SLCT | # | - -GRAPH- -+------+ # Row 1 | | DATA | # | | SLCT | # +------------+------+ # Row 2 | NAV GRAPH | ZOOM | # | | SLCT | # +------------+------+ #Setup for the Tk/Agg plotting backend self.figure = Figure(figsize = (width+1, height+2), dpi = 100) self.figure.subplots_adjust(bottom=0.15) self.axes = self.figure.add_subplot(111, autoscale_on=True) self.axes.xaxis.labelpad *= 3 self.canvas = FigureCanvasTkAgg(self.figure, master=self.root) self.canvas.get_tk_widget().grid(row=0, column=0, rowspan=2) #Setup for the mini-navigation figure self.nav_figure = Figure(figsize = ((width+1)*1.05, 1.8), dpi = 100) self.nav_figure.subplots_adjust(bottom=0.3) self.nav_axes = self.nav_figure.add_subplot(111, autoscale_on=False) self.nav_axes.xaxis.labelpad *= 2 self.nav_span = self.nav_axes.axvspan(0.0,1.0, facecolor='g', alpha=0.5) self.nav_handle1 = self.nav_axes.axvspan(0.00,0.025, facecolor='black', alpha=0.5) self.nav_handle2 = self.nav_axes.axvspan(0.975,1.00, facecolor='black', alpha=0.5) self.nav_canvas = FigureCanvasTkAgg(self.nav_figure, master=self.root) self.nav_canvas.get_tk_widget().grid(row=2, column=0) #Set the z-order to something high so that it works as an overlay self.nav_span.zorder = 1000 self.nav_handle1.zorder = 1001 self.nav_handle2.zorder = 1001 ## self.nav_axes.xaxis.set_major_locator(ticker.NullLocator()) self.nav_axes.yaxis.set_major_locator(ticker.NullLocator()) #Setup for the choosing the interval we want to examine self.interval_frame = Tk.Frame(self.root) self.interval_frame.grid(row=0, column=1, sticky=N+E) picker_label = Tk.Label(self.interval_frame, text="Data Intervals") picker_label.grid(row=0, column=0, sticky=N) self.interval_picker = Tk.Listbox(self.interval_frame, selectmode=Tk.BROWSE, exportselection=0) self.interval_picker.grid(row=1, column=0, sticky=N+W+E) width = 20 for (name, start, end) in self.intervals: string = format_span(start, end) width = max(width, len(string)) self.interval_picker.insert(Tk.END, string) self.interval_picker.config(width=width) self.interval_picker.bind("<Double-Button-1>", self.select_interval) self.interval_scrollbar = Tk.Scrollbar(self.interval_frame, command=self.interval_picker.yview) self.interval_picker.config(yscrollcommand=self.interval_scrollbar.set) self.interval_scrollbar.grid(row=1, column=1, sticky=N+S+W) picker_button = Tk.Button(self.interval_frame, text="Select interval", command=self.select_interval) picker_button.grid(row=2, column=0, sticky=N+W) #----Variables for picking the table from the database-------------- self.source_frame = Tk.Frame(self.root) self.source_frame.config(relief=Tk.GROOVE, borderwidth=2) self.source_frame.grid(row=1, column=1, sticky=N+W+E+S) source_label = Tk.Label(self.source_frame, text="Show/Hide plots") source_label.grid(column=0, columnspan=2, sticky=N) def set_var_callback(cb, data, checkbutton, var=None): if var is None: var = Tk.IntVar() def wrapper_callback(): var.set(var.get()) return cb(data, var.get()) checkbutton.config(variable=var, command=wrapper_callback) self.checkbuttons = [] for i,desc in enumerate(self.descriptors): checkbutton = Tk.Checkbutton(self.source_frame, text=desc.title) toggle = Tk.Checkbutton(self.source_frame, text=" ") color = self.colors[i % len(self.colors)] checkbutton.config(relief=Tk.SUNKEN, indicatoron=False) toggle.config(indicatoron=False, background=tk_color(lighten(color)), highlightbackground=tk_color(color), activebackground=tk_color(color), selectcolor=tk_color(color), state=ACTIVE) var = Tk.IntVar() set_var_callback(self.toggle_source, desc, checkbutton, var) set_var_callback(self.toggle_source, desc, toggle, var) self.color_map[desc.table_name] = color toggle.grid(column=0, row=i+1, sticky=N+W) checkbutton.grid(column=1, row=i+1, sticky=N+W) self.checkbuttons.append(checkbutton) self.style_count = 0 self.min_y = self.descriptors[0].min_y self.max_y = self.descriptors[0].max_y self.grabbing_navbar = False self.grabbing_handle = False self.grab_start = None self.handle_grabbed = None self.grab_reference = None def run(self): self.nav_figure.canvas.mpl_connect("button_press_event", self.mpl_on_press) self.nav_figure.canvas.mpl_connect("button_release_event", self.mpl_on_release) self.nav_figure.canvas.mpl_connect("motion_notify_event", self.mpl_on_motion) self.select_interval(index=0) self.interval_picker.selection_set(first=0) for desc, checkbutton in zip(self.descriptors, self.checkbuttons): checkbutton.select() self.toggle_source(desc, True) self.root.mainloop() def update_bounds(self): size = to_ordinal(self.absolute_end) - to_ordinal(self.absolute_start) x1 = to_ordinal(self.start_date) x2 = to_ordinal(self.end_date) self.axes.set_xbound(x1, x2) self.nav_span.set_xy([[x1, self.min_y], [x1, self.max_y], [x2, self.max_y], [x2, self.min_y], [x1, self.min_y]]) if x1 > x2: x1, x2 = x2, x1 self.nav_handle1.set_xy([[x1, self.min_y], [x1, self.max_y], [x1-size*0.025, self.max_y], [x1-size*0.025, self.min_y], [x1, self.min_y]]) self.nav_handle2.set_xy([[x2, self.min_y], [x2, self.max_y], [x2+size*0.025, self.max_y], [x2+size*0.025, self.min_y], [x2, self.min_y]]) locator = KenLocator(7.8) self.axes.xaxis.set_major_locator(locator) self.axes.xaxis.set_major_formatter(KenFormatter(locator)) self.axes.set_xlabel(format_span(self.start_date, self.end_date)) self.nav_axes.set_xlabel(format_timedelta(self.end_date-self.start_date)) def update_data(self): for identifier in self.data: view = self.data[identifier] view.load(self.absolute_start, self.absolute_end) self.collections[identifier].set_segments([view.export()]) self.nav_collections[identifier].set_segments([view.export()]) def select_interval(self, index=None): #Support direct invocation, invocation by event, and as a command if not isinstance(index, int): if not self.interval_picker.curselection(): return index = int(self.interval_picker.curselection()[0]) name, start, end = self.intervals[index] self.absolute_start = self.start_date = start self.absolute_end = self.end_date = end size = to_ordinal(start) - to_ordinal(end) self.nav_axes.set_xlim(to_ordinal(start)+size*0.025, to_ordinal(end)-size*0.025) locator = KenLocator(7.8) self.nav_axes.xaxis.set_major_locator(locator) self.nav_axes.xaxis.set_major_formatter(KenFormatter(locator)) self.update_data() self.update_bounds() self.redraw() def toggle_source(self, desc, enabled): if desc.table_name in self.data: if enabled: data = self.data[desc.table_name].export() self.axes.set_ylabel(desc.units) else: data = [] self.collections[desc.table_name].set_segments([data]) self.nav_collections[desc.table_name].set_segments([data]) self.redraw() elif enabled: self.axes.set_ylabel(desc.units) self.add_source(desc.table_name, desc.title) self.min_y = min(self.min_y, desc.min_y) self.max_y = max(self.max_y, desc.max_y) self.axes.set_ybound(self.min_y,self.max_y) self.nav_axes.set_ybound(self.min_y, self.max_y) ## self.axes.legend(loc=3) self.redraw() def redraw(self): self.figure.canvas.draw() self.nav_figure.canvas.draw() def add_source(self, identifier, title): view = SQLIntervalView(self.connection, identifier, self.absolute_start, self.absolute_end) self.data[identifier] = view colors = [self.color_map.get(identifier, self.colors[0])] col = DatetimeCollection([view.export()], colors=colors) col.set_label(title) self.collections[identifier] = col col2 = DatetimeCollection([view.export()], colors=colors) self.nav_collections[identifier] = col2 self.axes.add_collection(col) self.nav_axes.add_collection(col2) def mpl_on_press(self, event): if event.button != 1 or self.grabbing_navbar or self.grabbing_handle: return trans = self.nav_axes.transData.inverted() xdata = trans.transform((event.x, event.y))[0] if self.nav_handle1.contains(event)[0]: self.grabbing_handle = True self.handle_grabbed = 1 self.grab_start = xdata self.grab_reference = to_ordinal(min(self.start_date, self.end_date)) elif self.nav_handle2.contains(event)[0]: self.grabbing_handle = True self.handle_grabbed = 2 self.grab_start = xdata self.grab_reference = to_ordinal(max(self.start_date, self.end_date)) elif self.nav_span.contains(event)[0]: self.grabbing_navbar = True self.grab_start = xdata self.grab_reference = (to_ordinal(self.start_date), to_ordinal(self.end_date)) def move_navbar(self, pos): left_end = to_ordinal(self.absolute_start) right_end = to_ordinal(self.absolute_end) x1, x2 = self.grab_reference if x1 > x2: x1, x2 = x2, x1 diff = pos - self.grab_start if diff < 0 and x1 + diff < left_end: self.start_date = self.absolute_start self.end_date = from_ordinal(left_end + (x2 - x1)) elif diff > 0 and x2 + diff > right_end: self.end_date = self.absolute_end self.start_date = from_ordinal(right_end - (x2 - x1)) else: self.start_date = from_ordinal(x1 + diff) self.end_date = from_ordinal(x2 + diff) self.update_bounds() self.redraw() def move_handle(self, pos): left_end = to_ordinal(self.absolute_start) right_end = to_ordinal(self.absolute_end) diff = pos - self.grab_start new_pos = max(min(self.grab_reference + diff, right_end), left_end) new_date = from_ordinal(new_pos) if self.handle_grabbed == 1: if new_date > self.end_date: self.handle_grabbed = 2 self.start_date = self.end_date self.end_date = new_date else: self.start_date = new_date else: if new_date < self.start_date: self.handle_grabbed = 1 self.end_date = self.start_date self.start_date = new_date else: self.end_date = new_date self.update_bounds() self.redraw() def mpl_on_release(self, event): if event.button != 1: return trans = self.nav_axes.transData.inverted() xdata = trans.transform((event.x, event.y))[0] if self.grabbing_navbar: self.grabbing_navbar = False self.move_navbar(xdata) elif self.grabbing_handle: self.grabbing_handle = False self.move_handle(xdata) def mpl_on_motion(self, event): trans = self.nav_axes.transData.inverted() xdata = trans.transform((event.x, event.y))[0] if self.grabbing_navbar: self.move_navbar(xdata) elif self.grabbing_handle: self.move_handle(xdata)
class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.hsv_color = colorsys.rgb_to_hsv(0.0, 0.0, 1.0) self.hex_color = '#0000ff' self.color_list = ["red","blue","green","orange","purple"] self.parent = parent print "Loading model..." self.lux = Lux() fp = open(curdir+"/gauss_model.pkl"); self.gm = pickle.load(fp); fp.close() fp = open(curdir+"/memoized_binomial_data.pkl"); self.curve_data = pickle.load(fp); fp.close() fp = open(curdir+"/sampling_normalizer.pkl"); self.normalizer = pickle.load(fp); fp.close() print "Creating UI" self.initUI() self.update_output() self.replot() def update_output(self): (h, s, v) = self.hsv_color self.hsv_var.set("Hue: \t %2.1f \nSat:\t %2.1f \nValue:\t %2.1f" % (h*360,s*100,v*100)) items = self.lux.full_posterior((h * 360, s * 100, v * 100)) self.current_post = items desc = [ '{:<25} ({:.3f})\n'.format(items[i][0], items[i][1]) for i in range(25) ] self.display.config(state=NORMAL) self.display.delete(0, END) for i in range(25): self.display.insert(END, '{:<20} ({:.3f})'.format(items[i][0], items[i][1])) self.display.select_set(0, 0) def plot_lux_model(self, params,ax1,label,support,dim): cur_color='black' mu1,sh1,sc1,mu2,sh2,sc2 = params left_stach=gam_dist(sh1,scale=sc1); lbounds=left_stach.interval(0.99) right_stach=gam_dist(sh2,scale=sc2); rbounds=right_stach.interval(0.99) lx=np.linspace(mu1,-180); rx=np.linspace(mu2,360) s=3; ax1.plot(rx, [right_stach.sf(abs(y-mu2)) for y in rx],linewidth=s,c=cur_color); ax1.plot([1.01*mu1,0.99*mu2], [1.,1.], linewidth=s,c=cur_color) return ax1.plot(lx,[left_stach.sf(abs(y-mu1)) for y in lx],c=cur_color, linewidth=s); def plot_gm_model(self, params, ax, label, support): s=3 x = np.linspace(support[0],support[1],360) return ax.plot(x,norm.pdf(x,params[0],params[1]),c='red', linewidth=s), norm.pdf([params[0]],params[0],[params[1]])[0] def initUI(self): self.parent.title("Interactive LUX visualization") self.pack(fill=BOTH, expand=1) self.color_frame = Frame(self, border=1) self.color_frame.pack(side=LEFT) probe_title_var = StringVar(); probe_title_label = Label(self.color_frame, textvariable=probe_title_var, justify=CENTER, font = "Helvetica 16 bold italic") probe_title_var.set("Color Probe X"); probe_title_label.pack(side=TOP) self.hsv_var = StringVar() self.hsv_label = Label(self.color_frame, textvariable=self.hsv_var,justify=LEFT) h,s,v = self.hsv_color self.hsv_var.set("Hue: %2.1f \nSaturation: %2.1f \nValue: %2.1f" % (h*360,s*100,v*100)) self.hsv_label.pack(side=TOP) self.frame = Frame(self.color_frame, border=1, relief=SUNKEN, width=200, height=200) self.frame.pack(side=TOP) self.frame.config(bg=self.hex_color) self.frame.bind("<Button-1>",self.onChoose) self.btn = Button(self.color_frame, text="Select Color", command=self.onChoose) self.btn.pack(side=TOP) posterior_title_var = StringVar(); posterior_title_label = Label(self.color_frame, textvariable=posterior_title_var, justify=CENTER, font = "Helvetica 16 bold italic") posterior_title_var.set("\n\nLUX's Posterior"); posterior_title_label.pack(side=TOP) Label(self.color_frame, text="Double click to show details \n(Wait time dependent on computer)").pack(side=TOP) my_font = tkFont.Font(family="Courier", size=10) self.display = Listbox(self.color_frame, border=1, relief=SUNKEN, width=30, height=25, font=my_font) self.display.pack(side=TOP,fill=Y,expand=1) self.display.bind("<Double-Button-1>",self.onSelect) self.display_btn = Button(self.color_frame, text="Show details", command=self.onSelect) self.display_btn.pack(side=TOP) self.update_output() self.fig = Figure(figsize=(10,4), dpi=100) self.canvas = FigureCanvasTkAgg(self.fig, master=self) self.canvas.show() self.canvas.get_tk_widget().pack(side=LEFT, fill=BOTH, expand=1) self.canvas._tkcanvas.pack(side='top', fill='both', expand=1) def replot(self): def gb(x,i,t): #t is max value, i in number of bins, x is the thing to be binned if x==t: return i-1 elif x==0.0: return 0 return int(floor(float(x)*i/t)) hsv_title = [] j=self.display.curselection()[0] name = self.current_post[j][0] mult = lambda x: reduce(operator.mul, x) g_labels = []; lux_labels=[]; all_g_params=[] for i in range(3): def align_yaxis(ax1, v1, ax2, v2): """adjust ax2 ylimit so that v2 in ax2 is aligned to v1 in ax1""" _, y1 = ax1.transData.transform((0, v1)) _, y2 = ax2.transData.transform((0, v2)) inv = ax2.transData.inverted() _, dy = inv.transform((0, 0)) - inv.transform((0, y1-y2)) miny, maxy = ax2.get_ylim() ax2.set_ylim(miny, maxy+dy) subplot = self.fig.add_subplot(4,1,i+1) dim_label = ["H", "S","V"][i] subplot.set_ylabel(r"$P(k^{true}_{%s}|x)$" % ["H", "S","V"][i] ) curve_data = self.curve_data[name][i] scale = lambda x,a=0.3,b=0.9: (b-a)*(x)+a p_x = lambda x: self.normalizer[i][gb(x,len(self.normalizer[i]),[360,100,100][i])] max_p_x = max(self.normalizer[i]) #1 is white, 0 is black. so we want highly probable thigns to be black.. if self.lux.get_adj(self.current_post[j][0]): support = [[-180,180], [0,100],[0,100]][i] pp = lambda x,i: x-360 if i==0 and x>180 else x hacky_solution = [360,100,100][i] w = 1.5 if i==0 else 1 conv = lambda x: x*support[1]/len(curve_data) bar_colors = ["%s" % (scale(1-p_x(conv(x))/max_p_x)) for x in range(len(curve_data))] bar1 = subplot.bar([pp(atan2(sin((x*hacky_solution/len(curve_data))*pi/180),cos((x*hacky_solution/len(curve_data))*pi/180))*180/pi,i) for x in range(len(curve_data))],[x/max(curve_data) for x in curve_data], label="%s data" % j,ec="black",width=w,linewidth=0,color=bar_colors) else: support = [[0,360], [0,100],[0,100]][i] w = 1.5 if i==0 else 1 conv = lambda x: x*support[1]/len(curve_data) bar_colors = ["%s" % (scale(1-p_x(conv(x))/max_p_x)) for x in range(len(curve_data))] bar1 = subplot.bar([x*support[1]/len(curve_data) for x in range(len(curve_data))],[x/max(curve_data) for x in curve_data], label="%s data" % name[0],ec="black",width=w,linewidth=0,color=bar_colors) pp = lambda x,*args: x point = pp(self.hsv_color[i]*[360,100,100][i],i) hsv_title.append(point) probeplot = subplot.plot([point,point], [0,1],linewidth=3,c='blue',label="Probe") #for j in range(5): lux_plot = self.plot_lux_model(self.lux.get_params(self.current_post[j][0])[i], subplot, self.current_post[j][0],support, i) subplot2 = subplot.twinx() gm_plot,gm_height = self.plot_gm_model([pp(g_param,i) for g_param in self.gm[self.current_post[j][0]][0][i]], subplot2, self.current_post[j][0], support) extra = Rectangle((0, 0), 1, 1, fc="w", fill=False, edgecolor='none', linewidth=0) subplot.legend([extra], [["Hue", "Saturation", "Value"][i]],loc=2,frameon=False) if i==0: legend_set=lux_plot+[extra,extra,extra]+gm_plot+[extra,extra,extra] lux_params = self.lux.get_params(self.current_post[j][0])[i] g_params = [pp(g_param,i) for g_param in self.gm[self.current_post[j][0]][0][i]] all_g_params.append(g_params) g_labels.append(r"$\mu^{%s}=$%2.2f, $\sigma^{%s}$=%2.2f" % (dim_label, g_params[0],dim_label,g_params[1])) #lux_labels.append(r"$\mu^{L,%s}=$%2.2f, $E[\tau^{L,%s}]$=%2.2f, $\alpha^{L,%s}$=%2.2f, $\beta^{L,%s}$=%2.2f, $\mu^{U,%s}=$%2.2f, $E[\tau^{L,%s}]$=%2.2f, $\alpha^{U,%s}$=%2.2f, $\beta^{U,%s}$=%2.2f" % (dim_label, lux_params[0],dim_label, (lux_params[0]-lux_params[1]*lux_params[2]),dim_label,lux_params[1],dim_label, lux_params[2],dim_label,lux_params[3],dim_label,(lux_params[3]+lux_params[4]*lux_params[5]),dim_label, lux_params[4],dim_label,lux_params[5])) lux_labels.append(r"$\mu^{L,%s}=$%2.2f, $\alpha^{L,%s}$=%2.2f, $\beta^{L,%s}$=%2.2f, $\mu^{U,%s}=$%2.2f, $\alpha^{U,%s}$=%2.2f, $\beta^{U,%s}$=%2.2f" % (dim_label, lux_params[0],dim_label, lux_params[1],dim_label, lux_params[2],dim_label,lux_params[3],dim_label,lux_params[4],dim_label,lux_params[5])) subplot.set_xlim(support[0],support[1]) subplot.set_ylim(0,1.05) subplot2.set_xlim(support[0],support[1]) subplot2.set_ylabel(r"$P(x|Gaussian_{%s})$" % ["H", "S","V"][i]) align_yaxis(subplot, 1., subplot2, gm_height) leg_loc =(0.9,0.2) datum = [x*[360,100,100][i] for i,x in enumerate(self.hsv_color)]; phi_value = self.lux.get_phi(datum,self.current_post[j][0]) #gauss_value = mult([norm.pdf(datum[i],all_g_params[i][0],all_g_params[i][1]) for i in range(3)]) leg=self.fig.legend(probeplot+legend_set, ["Probe X"]+ [r"$\mathbf{\phi}_{%s}(X)=\mathbf{%2.5f}$; $\mathbf{\alpha}=\mathbf{%2.4f}$" % (self.current_post[j][0],phi_value,self.lux.get_avail(self.current_post[j][0]))]+lux_labels+ [r"$Normal^{Hue}_{%s}$; $prior(%s)=%2.4f$" % (self.current_post[j][0],self.current_post[j][0], self.gm[self.current_post[j][0]][2])]+[g_labels[0]+"; "+g_labels[1]+"; "+g_labels[2]] , loc=8, handletextpad=4,labelspacing=0.1) self.fig.suptitle("%s" % name, size=30) print "done replotting" def onChoose(self, *args): try: ((red,green,blue), hx) = tkColorChooser.askcolor() except: print "I think you hit cancel" return self.hex_color = hx self.hsv_color = colorsys.rgb_to_hsv(red/255.0, green/255.0, blue/255.0) self.frame.config(bg=hx) self.update_output() self.fig.clear() self.replot() self.canvas.draw() def onSelect(self, *args): self.fig.clear() self.replot() self.canvas.draw()
def plot( self, cmap: str = "viridis", interpolation: str = "none", title: str = None, colorbar: bool = True, labels: bool = True, display_names: bool = False, ax: plt.Figure = None, ) -> plt.Figure: """Plot the results of the spatial tournament. Parameters ---------- cmap : str, optional A matplotlib colour map, full list can be found at http://matplotlib.org/examples/color/colormaps_reference.html interpolation : str, optional A matplotlib interpolation, full list can be found at http://matplotlib.org/examples/images_contours_and_fields/interpolation_methods.html title : str, optional A title for the plot colorbar : bool, optional Choose whether the colorbar should be included or not labels : bool, optional Choose whether the axis labels and ticks should be included display_names : bool, optional Choose whether to display the names of the strategies ax: matplotlib axis Allows the plot to be written to a given matplotlib axis. Default is None. Returns ---------- figure : matplotlib figure A heat plot of the results of the spatial tournament """ if ax is None: fig, ax = plt.subplots() else: ax = ax fig = ax.get_figure() mat = ax.imshow(self.data, cmap=cmap, interpolation=interpolation) width = len(self.data) / 2 height = width fig.set_size_inches(width, height) plt.xlabel("turns") ax.tick_params(axis="both", which="both", length=0) if display_names: plt.yticks( range(len(self.opponents)), [str(player) for player in self.opponents] ) else: plt.yticks([0, len(self.opponents) - 1], [0, 1]) plt.ylabel("Probability of cooperation") if not labels: plt.axis("off") if title is not None: plt.title(title) if colorbar: max_score = 0 min_score = 1 ticks = [min_score, 1 / 2, max_score] divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.2) cbar = fig.colorbar(mat, cax=cax, ticks=ticks) plt.tight_layout() return fig
class ChartDialog(wx.Dialog): """Chart dialog frontend to matplotlib""" chart_types = [ "plot" ] def __init__(self, parent, *args, **kwargs): wx.Dialog.__init__(self, parent, -1, _("Insert chart"), *args, size=(900, 700), style=wx.RESIZE_BORDER, **kwargs) self.splitter = wx.SplitterWindow(self, -1, style=wx.SP_LIVE_UPDATE) self.splitter.parent = self # Create a CustomTreeCtrl instance self.tree = ChartTree(self.splitter, style=wx.BORDER_SUNKEN) self.figure_panel = FigurePanel(self.splitter) # Dummy figure self.figure = Figure(facecolor='white') ax = self.figure.add_subplot(111) ax.xaxis.set_picker(5) ax.xaxis.name = "xaxis" ax.yaxis.set_picker(5) ax.yaxis.name = "yaxis" plt = ax.plot([(x/10.0)**2 for x in xrange(1000)], picker=5) plt[-1].name = "test" self.figure_panel.update(self.figure) # Split Window self.splitter.SplitVertically(self.tree, self.figure_panel) self.splitter.SetMinimumPaneSize(10) self.splitter.SetSashPosition(400) # Buttons self.button_add = wx.Button(self, wx.ID_ADD) self.button_remove = wx.Button(self, wx.ID_REMOVE) self.button_cancel = wx.Button(self, wx.ID_CANCEL) self.button_ok = wx.Button(self, wx.ID_OK) self.button_add.Bind(wx.EVT_BUTTON, self.OnAdd) self._layout() def _layout(self): """Sizer layout""" left_sizer = wx.FlexGridSizer(cols=1) left_button_sizer = wx.FlexGridSizer(cols=5) left_sizer.Add(self.splitter, 0, wx.EXPAND) left_sizer.Add(left_button_sizer, 0, wx.EXPAND) left_button_sizer.Add(self.button_add, 1, wx.EXPAND | wx.ALL, 4) left_button_sizer.Add(self.button_remove, 1, wx.EXPAND | wx.ALL, 4) left_button_sizer.Add(wx.Panel(self, -1), 1, wx.EXPAND | wx.ALL, 4) left_button_sizer.Add(self.button_cancel, 1, wx.EXPAND | wx.ALL, 4) left_button_sizer.Add(self.button_ok, 1, wx.EXPAND | wx.ALL, 4) left_sizer.AddGrowableRow(0) left_sizer.AddGrowableCol(0) left_button_sizer.AddGrowableCol(2) self.SetSizer(left_sizer) self.Layout() def add_chart(self, chart_type): """Adds chart to figure after current position in the tree""" self.tree.add_chart(chart_type) # Event handlers def OnAdd(self, event): """Add button event handler""" dlg = wx.SingleChoiceDialog(self, _('Add chart to figure'), _('Select chart type'), self.chart_types, wx.CHOICEDLG_STYLE) if dlg.ShowModal() == wx.ID_OK: self.add_chart(dlg.GetStringSelection()) dlg.Destroy()
class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.hsv_color = colorsys.rgb_to_hsv(0.0, 0.0, 1.0) self.hex_color = '#0000ff' self.color_list = ["red","blue","green","orange","purple"] self.parent = parent print "Getting Model" self.lux = lux.LUX("lux.xml") print "Creating UI" self.initUI() self.update_output() def update_output(self): (h, s, v) = self.hsv_color items = self.lux.full_posterior((h * 360, s * 100, v * 100)) self.current_post = items desc = [ '{} ({:.3f})\n'.format(items[i][0], items[i][1]) for i in range(25) ] self.display.config(state=NORMAL) self.display.delete(1.0, END) self.display.insert(END, ''.join(desc)) self.display.config(state=DISABLED) def make_plotter(self, params,ax1,label,cur_color,support): mu1,sh1,sc1,mu2,sh2,sc2 = params left_stach=gam_dist(sh1,scale=sc1); lbounds=left_stach.interval(0.99) right_stach=gam_dist(sh2,scale=sc2); rbounds=right_stach.interval(0.99) lx=np.linspace(mu1,-180); rx=np.linspace(mu2,360) s=3; #cur_color='black' ax1.plot(rx, [1-right_stach.cdf(abs(y-mu2)) for y in rx],linewidth=s,c=cur_color); ax1.plot([1.01*mu1,0.99*mu2], [1,1], linewidth=s,c=cur_color) return ax1.plot(lx,[1-left_stach.cdf(abs(y-mu1)) for y in lx],c=cur_color, label=r"$\phi^{Hue}_{%s}$" % label,linewidth=s); def initUI(self): self.parent.title("Interactive LUX visualization") self.pack(fill=BOTH, expand=1) self.color_frame = Frame(self, border=1) self.color_frame.pack(side=LEFT) self.frame = Frame(self.color_frame, border=1, relief=SUNKEN, width=100, height=100) #self.frame.place(x=160, y=30) self.frame.pack(side=TOP) self.frame.config(bg=self.hex_color) self.btn = Button(self.color_frame, text="Select Color", command=self.onChoose) self.btn.pack(side=TOP) #self.btn.place(x=30, y=30) self.display = Text(self, border=1, relief=SUNKEN, width=30, height=5) #self.display.place(x=280, y=30) self.display.pack(side=LEFT,fill=Y,expand=1) self.update_output() self.fig = Figure(figsize=(10,4), dpi=100) self.replot() self.canvas = FigureCanvasTkAgg(self.fig, master=self) self.canvas.show() self.canvas.get_tk_widget().pack(side=LEFT, fill=BOTH, expand=1) self.canvas._tkcanvas.pack(side='top', fill='both', expand=1) def replot(self): hsv_title = [] for i in range(3): if self.lux.get_adj(self.current_post[0][0]): support = [[-180,180], [0,100],[0,100]][i] pp = lambda x,i: x-360 if i==0 and x>180 else x else: support = [[0,360], [0,100],[0,100]][i] pp = lambda x,*args: x subplot = self.fig.add_subplot(3,1,i+1) subplot.set_xlim(support[0],support[1]) subplot.set_ylabel("%s" % ["Hue", "Saturation","Value"][i]) point = pp(self.hsv_color[i]*[360,100,100][i],i) hsv_title.append(point) probeplot = subplot.plot([point,point], [0,1],linewidth=3,c='black',label="Probe") legend_set = [] for j in range(5): test = self.make_plotter(self.lux.get_params(self.current_post[j][0])[i], subplot, self.current_post[j][0],self.color_list[j],support) if type(test)==type([]): legend_set+=test else: legend_set.append(test) self.fig.legend(legend_set, [r"$\phi_{%s}$; $\alpha=%2.4f$" % (x[0],self.lux.get_avail(x[0])) for x in self.current_post[:5]], loc=1) self.fig.suptitle("HSV (%2.2f,%2.2f,%2.2f) top 5 Phi curves" % (hsv_title[0],hsv_title[1],hsv_title[2])) def onChoose(self): ((red,green,blue), hx) = tkColorChooser.askcolor() self.hex_color = hx self.hsv_color = colorsys.rgb_to_hsv(red/255.0, green/255.0, blue/255.0) self.frame.config(bg=hx) self.update_output() self.fig.clear() self.replot() self.canvas.draw()
def __init__(self, width, height): self.path = config.find_options("general.cfg")['database'] self.descriptors = config.find_graphs("graphs.cfg") self.data = {} self.collections = {} self.nav_collections = {} self.color_map = {} self.connection = sql.connect(self.path, detect_types=(sql.PARSE_COLNAMES|sql.PARSE_DECLTYPES)) self.root = Tk.Tk() self.root.wm_title("Historical Data Viewer") self.intervals = self.connection.execute("SELECT * FROM intervals ORDER BY start;").fetchall() self.intervals = list(reversed(self.intervals)) #Grid layout: # Col 0 Col 1 # +------------+------+ # Row 0 | | ITVL | # | ZOOM | SLCT | # | - -GRAPH- -+------+ # Row 1 | | DATA | # | | SLCT | # +------------+------+ # Row 2 | NAV GRAPH | ZOOM | # | | SLCT | # +------------+------+ #Setup for the Tk/Agg plotting backend self.figure = Figure(figsize = (width+1, height+2), dpi = 100) self.figure.subplots_adjust(bottom=0.15) self.axes = self.figure.add_subplot(111, autoscale_on=True) self.axes.xaxis.labelpad *= 3 self.canvas = FigureCanvasTkAgg(self.figure, master=self.root) self.canvas.get_tk_widget().grid(row=0, column=0, rowspan=2) #Setup for the mini-navigation figure self.nav_figure = Figure(figsize = ((width+1)*1.05, 1.8), dpi = 100) self.nav_figure.subplots_adjust(bottom=0.3) self.nav_axes = self.nav_figure.add_subplot(111, autoscale_on=False) self.nav_axes.xaxis.labelpad *= 2 self.nav_span = self.nav_axes.axvspan(0.0,1.0, facecolor='g', alpha=0.5) self.nav_handle1 = self.nav_axes.axvspan(0.00,0.025, facecolor='black', alpha=0.5) self.nav_handle2 = self.nav_axes.axvspan(0.975,1.00, facecolor='black', alpha=0.5) self.nav_canvas = FigureCanvasTkAgg(self.nav_figure, master=self.root) self.nav_canvas.get_tk_widget().grid(row=2, column=0) #Set the z-order to something high so that it works as an overlay self.nav_span.zorder = 1000 self.nav_handle1.zorder = 1001 self.nav_handle2.zorder = 1001 ## self.nav_axes.xaxis.set_major_locator(ticker.NullLocator()) self.nav_axes.yaxis.set_major_locator(ticker.NullLocator()) #Setup for the choosing the interval we want to examine self.interval_frame = Tk.Frame(self.root) self.interval_frame.grid(row=0, column=1, sticky=N+E) picker_label = Tk.Label(self.interval_frame, text="Data Intervals") picker_label.grid(row=0, column=0, sticky=N) self.interval_picker = Tk.Listbox(self.interval_frame, selectmode=Tk.BROWSE, exportselection=0) self.interval_picker.grid(row=1, column=0, sticky=N+W+E) width = 20 for (name, start, end) in self.intervals: string = format_span(start, end) width = max(width, len(string)) self.interval_picker.insert(Tk.END, string) self.interval_picker.config(width=width) self.interval_picker.bind("<Double-Button-1>", self.select_interval) self.interval_scrollbar = Tk.Scrollbar(self.interval_frame, command=self.interval_picker.yview) self.interval_picker.config(yscrollcommand=self.interval_scrollbar.set) self.interval_scrollbar.grid(row=1, column=1, sticky=N+S+W) picker_button = Tk.Button(self.interval_frame, text="Select interval", command=self.select_interval) picker_button.grid(row=2, column=0, sticky=N+W) #----Variables for picking the table from the database-------------- self.source_frame = Tk.Frame(self.root) self.source_frame.config(relief=Tk.GROOVE, borderwidth=2) self.source_frame.grid(row=1, column=1, sticky=N+W+E+S) source_label = Tk.Label(self.source_frame, text="Show/Hide plots") source_label.grid(column=0, columnspan=2, sticky=N) def set_var_callback(cb, data, checkbutton, var=None): if var is None: var = Tk.IntVar() def wrapper_callback(): var.set(var.get()) return cb(data, var.get()) checkbutton.config(variable=var, command=wrapper_callback) self.checkbuttons = [] for i,desc in enumerate(self.descriptors): checkbutton = Tk.Checkbutton(self.source_frame, text=desc.title) toggle = Tk.Checkbutton(self.source_frame, text=" ") color = self.colors[i % len(self.colors)] checkbutton.config(relief=Tk.SUNKEN, indicatoron=False) toggle.config(indicatoron=False, background=tk_color(lighten(color)), highlightbackground=tk_color(color), activebackground=tk_color(color), selectcolor=tk_color(color), state=ACTIVE) var = Tk.IntVar() set_var_callback(self.toggle_source, desc, checkbutton, var) set_var_callback(self.toggle_source, desc, toggle, var) self.color_map[desc.table_name] = color toggle.grid(column=0, row=i+1, sticky=N+W) checkbutton.grid(column=1, row=i+1, sticky=N+W) self.checkbuttons.append(checkbutton) self.style_count = 0 self.min_y = self.descriptors[0].min_y self.max_y = self.descriptors[0].max_y self.grabbing_navbar = False self.grabbing_handle = False self.grab_start = None self.handle_grabbed = None self.grab_reference = None
class DoubleSliderTestApp: def __init__(self, width, height): self.root = Tk.Tk() self.root.wm_title("Double Slider Test") self.plot = Figure(figsize = (width+1, height+2), dpi=72) self.axes = self.plot.add_subplot(111) self.canvas = FigureCanvasTkAgg(self.plot, master=self.root) self.canvas.get_tk_widget().grid(row=0) self.nav_plot = Figure(figsize = (width+1, 2), dpi=72) self.nav_axes = self.nav_plot.add_subplot(111) self.nav_canvas = FigureCanvasTkAgg(self.nav_plot, master=self.root) self.nav_canvas.get_tk_widget().grid(row=1) self.nav_plot.subplots_adjust(bottom=0.2) self.agg_canvas = self.nav_canvas.get_tk_widget() self.slider = DoubleSlider(self.root, round=lambda x: round(x, 2), left_bound=2.0, right_bound=3.0) self.slider.grid(row=2, sticky=Tk.W+Tk.E+Tk.N+Tk.S) data = [(2.0, 0.6), (2.1, 0.9), (2.2, 0.7), (2.3, 0.8), (2.4, 0.5), (2.6, 0.2), (2.7, 0.3), (2.8, 0.6), (2.9, 0.4), (3.0, 0.1)] self.axes.set_xbound(2.0, 3.0) self.axes.add_collection(LineCollection([data])) self.nav_axes.set_xbound(2.0, 3.0) self.nav_axes.add_collection(LineCollection([data])) def run(self): self.plot.canvas.draw() self.nav_plot.canvas.draw() left_pad = self.nav_plot.subplotpars.left * self.nav_plot.get_figwidth() * self.nav_plot.dpi right_pad = (1-self.nav_plot.subplotpars.right) * self.nav_plot.get_figwidth() * self.nav_plot.dpi self.slider.config(left_padding=left_pad, right_padding=right_pad) def update_limits(left, right): self.agg_canvas.delete("OVERLAY") trans = blended_transform_factory(self.nav_axes.transData, self.nav_axes.transAxes) corner1 = trans.transform_point([left, 1]).tolist() corner2 = trans.transform_point([self.slider.left_bound, 0]).tolist() self.agg_canvas.create_rectangle([corner1, corner2], stipple="gray25", fill="gray",tags="OVERLAY") corner3 = trans.transform_point((right, 1)).tolist() corner4 = trans.transform_point((self.slider.right_bound, 0)).tolist() self.agg_canvas.create_rectangle([corner3, corner4], stipple="gray25", fill="gray",tags="OVERLAY") self.axes.set_xbound(left, right) self.plot.canvas.draw() self.slider.config(on_change=update_limits) self.slider.init() self.root.mainloop()
def __init__(self, parent=None): """ Initialization and set up """ # Base class QMainWindow.__init__(self, parent) # Mantid configuration config = ConfigService.Instance() self._instrument = config["default.instrument"] # Central widget self.centralwidget = QWidget(self) # UI Window (from Qt Designer) self.ui = load_ui(__file__, 'MainWindow.ui', baseinstance=self) mpl_layout = QVBoxLayout() self.ui.graphicsView.setLayout(mpl_layout) self.fig = Figure() self.canvas = FigureCanvas(self.fig) self.ui.mainplot = self.fig.add_subplot(111, projection='mantid') mpl_layout.addWidget(self.canvas) # Do initialize plotting vecx, vecy, xlim, ylim = self.computeMock() self.mainline = self.ui.mainplot.plot(vecx, vecy, 'r-') leftx = [xlim[0], xlim[0]] lefty = [ylim[0], ylim[1]] self.leftslideline = self.ui.mainplot.plot(leftx, lefty, 'b--') rightx = [xlim[1], xlim[1]] righty = [ylim[0], ylim[1]] self.rightslideline = self.ui.mainplot.plot(rightx, righty, 'g--') upperx = [xlim[0], xlim[1]] uppery = [ylim[1], ylim[1]] self.upperslideline = self.ui.mainplot.plot(upperx, uppery, 'b--') lowerx = [xlim[0], xlim[1]] lowery = [ylim[0], ylim[0]] self.lowerslideline = self.ui.mainplot.plot(lowerx, lowery, 'g--') self.canvas.mpl_connect('button_press_event', self.on_mouseDownEvent) # Set up horizontal slide (integer) and string value self._leftSlideValue = 0 self._rightSlideValue = 99 self.ui.horizontalSlider.setRange(0, 100) self.ui.horizontalSlider.setValue(self._leftSlideValue) self.ui.horizontalSlider.setTracking(True) self.ui.horizontalSlider.setTickPosition(QSlider.NoTicks) self.ui.horizontalSlider.valueChanged.connect(self.move_leftSlider) self.ui.horizontalSlider_2.setRange(0, 100) self.ui.horizontalSlider_2.setValue(self._rightSlideValue) self.ui.horizontalSlider_2.setTracking(True) self.ui.horizontalSlider_2.setTickPosition(QSlider.NoTicks) self.ui.horizontalSlider_2.valueChanged.connect(self.move_rightSlider) # self.connect(self.ui.lineEdit_3, QtCore.SIGNAL("textChanged(QString)"), # self.set_startTime) self.ui.lineEdit_3.setValidator(QDoubleValidator(self.ui.lineEdit_3)) self.ui.pushButton_setT0.clicked.connect(self.set_startTime) # self.connect(self.ui.lineEdit_4, QtCore.SIGNAL("textChanged(QString)"), # self.set_stopTime) self.ui.lineEdit_4.setValidator(QDoubleValidator(self.ui.lineEdit_4)) self.ui.pushButton_setTf.clicked.connect(self.set_stopTime) # File loader self.scanEventWorkspaces() self.ui.pushButton_refreshWS.clicked.connect(self.scanEventWorkspaces) self.ui.pushButton_browse.clicked.connect(self.browse_File) self.ui.pushButton_load.clicked.connect(self.load_File) self.ui.pushButton_3.clicked.connect(self.use_existWS) # Set up time self.ui.lineEdit_3.setValidator(QDoubleValidator(self.ui.lineEdit_3)) self.ui.lineEdit_4.setValidator(QDoubleValidator(self.ui.lineEdit_4)) # Filter by time self.ui.pushButton_filterTime.clicked.connect(self.filterByTime) # Filter by log value self.ui.lineEdit_5.setValidator(QDoubleValidator(self.ui.lineEdit_5)) self.ui.lineEdit_6.setValidator(QDoubleValidator(self.ui.lineEdit_6)) self.ui.lineEdit_7.setValidator(QDoubleValidator(self.ui.lineEdit_7)) self.ui.lineEdit_8.setValidator(QDoubleValidator(self.ui.lineEdit_8)) self.ui.lineEdit_9.setValidator(QDoubleValidator(self.ui.lineEdit_9)) self.ui.lineEdit_5.textChanged.connect(self.set_minLogValue) self.ui.lineEdit_6.textChanged.connect(self.set_maxLogValue) dirchangeops = ["Both", "Increase", "Decrease"] self.ui.comboBox_4.addItems(dirchangeops) logboundops = ["Centre", "Left"] self.ui.comboBox_5.addItems(logboundops) self.ui.pushButton_4.clicked.connect(self.plotLogValue) self.ui.pushButton_filterLog.clicked.connect(self.filterByLogValue) # Set up help button self.ui.helpBtn.clicked.connect(self.helpClicked) # Set up vertical slide self._upperSlideValue = 99 self._lowerSlideValue = 0 self.ui.verticalSlider.setRange(0, 100) self.ui.verticalSlider.setValue(self._upperSlideValue) self.ui.verticalSlider.setTracking(True) self.ui.verticalSlider.valueChanged.connect(self.move_upperSlider) self.ui.verticalSlider_2.setRange(0, 100) self.ui.verticalSlider_2.setValue(self._lowerSlideValue) self.ui.verticalSlider_2.setTracking(True) self.ui.verticalSlider_2.valueChanged.connect(self.move_lowerSlider) # Set up for filtering (advanced setup) self._tofcorrection = False self.ui.checkBox_fastLog.setChecked(False) self.ui.checkBox_filterByPulse.setChecked(False) self.ui.checkBox_from1.setChecked(False) self.ui.checkBox_groupWS.setChecked(True) self.ui.comboBox_tofCorr.currentIndexChanged.connect(self.showHideEi) self.ui.pushButton_refreshCorrWSList.clicked.connect(self._searchTableWorkspaces) self.ui.lineEdit_Ei.setValidator(QDoubleValidator(self.ui.lineEdit_Ei)) self.ui.label_Ei.hide() self.ui.lineEdit_Ei.hide() self.ui.label_Ei_2.hide() self.ui.comboBox_corrWS.hide() self.ui.pushButton_refreshCorrWSList.hide() # Set up for workspaces self._dataWS = None self._sampleLogNames = [] self._sampleLog = None # Side information self.ui.label_mean.hide() self.ui.label_meanvalue.hide() self.ui.label_avg.hide() self.ui.label_timeAvgValue.hide() self.ui.label_freq.hide() self.ui.label_freqValue.hide() self.ui.label_logname.hide() self.ui.label_lognamevalue.hide() self.ui.label_logsize.hide() self.ui.label_logsizevalue.hide() # Default self._defaultdir = os.getcwd() # register startup mantid.UsageService.registerFeatureUsage("Interface", "EventFilter", False)
class HistoricalViewerApp: line_styles = ["solid"] colors = [ (0.0, 0.0, 1.0, 1.0), #Blue (1.0, 0.0, 0.0, 1.0), #Red (0.0, 1.0, 0.0, 1.0), #Green (1.0, 1.0, 0.0, 1.0) ] def __init__(self, width, height): self.path = config.find_options("general.cfg")['database'] self.descriptors = config.find_graphs("graphs.cfg") self.data = {} self.collections = {} self.nav_collections = {} self.color_map = {} self.connection = sql.connect(self.path, detect_types=(sql.PARSE_COLNAMES|sql.PARSE_DECLTYPES)) self.root = Tk.Tk() self.root.wm_title("Historical Data Viewer") self.intervals = self.connection.execute("SELECT * FROM intervals ORDER BY start;").fetchall() self.intervals = list(reversed(self.intervals)) #Grid layout: # Col 0 Col 1 # +------------+------+ # Row 0 | | ITVL | # | ZOOM | SLCT | # | - -GRAPH- -+------+ # Row 1 | | DATA | # | | SLCT | # +------------+------+ # Row 2 | NAV GRAPH | ZOOM | # | | SLCT | # +------------+------+ #Setup for the Tk/Agg plotting backend self.figure = Figure(figsize = (width+1, height+2), dpi = 100) self.figure.subplots_adjust(bottom=0.15) self.axes = self.figure.add_subplot(111, autoscale_on=True) #self.axes.xaxis.labelpad *= 3 self.canvas = FigureCanvasTkAgg(self.figure, master=self.root) self.canvas.get_tk_widget().grid(row=0, column=0, rowspan=2) #Setup for the mini-navigation figure self.nav_figure = Figure(figsize = ((width+1)*1.05, 1.8), dpi = 100) #self.nav_figure.subplots_adjust(bottom=0.3) self.nav_axes = self.nav_figure.add_subplot(111, autoscale_on=False) #self.nav_axes.xaxis.labelpad *= 2 self.nav_canvas = FigureCanvasTkAgg(self.nav_figure, master=self.root) self.nav_canvas.get_tk_widget().grid(row=2, column=0) self.nav_axes.yaxis.set_major_locator(ticker.NullLocator()) #Setup for the slider def scale_to_data(left, right, x): return from_ordinal(to_ordinal(left) + x * (to_ordinal(right) - to_ordinal(left))) def data_to_scale(left, right, x): return (to_ordinal(x) - to_ordinal(left)) / (to_ordinal(right) - to_ordinal(left)) self.slider = DoubleSlider(self.root, left_bound=datetime(1999,1,1), right_bound=datetime(1999,1,28), data_to_scale=data_to_scale, scale_to_data=scale_to_data, set_on_drag=False, on_change=self.update_bounds, on_drag=lambda left, right: self.update_bounds(left, right, True)) self.slider.grid(row=3, column=0, sticky=W+E) #Setup for the choosing the interval we want to examine self.interval_frame = Tk.Frame(self.root) self.interval_frame.grid(row=0, column=1, sticky=N+E) picker_label = Tk.Label(self.interval_frame, text="Data Intervals") picker_label.grid(row=0, column=0, sticky=N) self.interval_picker = Tk.Listbox(self.interval_frame, selectmode=Tk.BROWSE, exportselection=0) self.interval_picker.grid(row=1, column=0, sticky=N+W+E) width = 20 for (name, start, end) in self.intervals: string = format_span(start, end) width = max(width, len(string)) self.interval_picker.insert(Tk.END, string) self.interval_picker.config(width=width) self.interval_picker.bind("<Double-Button-1>", self.select_interval) self.interval_scrollbar = Tk.Scrollbar(self.interval_frame, command=self.interval_picker.yview) self.interval_picker.config(yscrollcommand=self.interval_scrollbar.set) self.interval_scrollbar.grid(row=1, column=1, sticky=N+S+W) picker_button = Tk.Button(self.interval_frame, text="Select interval", command=self.select_interval) picker_button.grid(row=2, column=0, sticky=N+W) #----Variables for picking the table from the database-------------- self.source_frame = Tk.Frame(self.root) self.source_frame.config(relief=Tk.GROOVE, borderwidth=2) self.source_frame.grid(row=1, column=1, sticky=N+W+E+S) source_label = Tk.Label(self.source_frame, text="Show/Hide plots") source_label.grid(column=0, columnspan=2, sticky=N) def set_var_callback(cb, data, checkbutton, var=None): if var is None: var = Tk.IntVar() def wrapper_callback(): var.set(var.get()) return cb(data, var.get()) checkbutton.config(variable=var, command=wrapper_callback) self.checkbuttons = [] for i,desc in enumerate(self.descriptors): checkbutton = Tk.Checkbutton(self.source_frame, text=desc.title) toggle = Tk.Checkbutton(self.source_frame, text=" ") color = self.colors[i % len(self.colors)] checkbutton.config(relief=Tk.SUNKEN, indicatoron=False) toggle.config(indicatoron=False, background=tk_color(lighten(color)), highlightbackground=tk_color(color), activebackground=tk_color(color), selectcolor=tk_color(color), state=ACTIVE) var = Tk.IntVar() set_var_callback(self.toggle_source, desc, checkbutton, var) set_var_callback(self.toggle_source, desc, toggle, var) self.color_map[desc.table_name] = color toggle.grid(column=0, row=i+1, sticky=N+W) checkbutton.grid(column=1, row=i+1, sticky=N+W) self.checkbuttons.append(checkbutton) self.style_count = 0 self.min_y = self.descriptors[0].min_y self.max_y = self.descriptors[0].max_y def run(self): left_pad = self.nav_figure.subplotpars.left * self.nav_figure.get_figwidth() * self.nav_figure.dpi right_pad = (1-self.nav_figure.subplotpars.right) * self.nav_figure.get_figwidth() * self.nav_figure.dpi self.slider.config(left_padding=left_pad, right_padding=right_pad) self.figure.canvas.draw() self.nav_figure.canvas.draw() self.slider.init() self.select_interval(index=0) self.interval_picker.selection_set(first=0) for desc, checkbutton in zip(self.descriptors, self.checkbuttons): checkbutton.select() self.toggle_source(desc, True) locator = KenLocator(7.8) self.nav_axes.xaxis.set_major_locator(locator) self.nav_axes.xaxis.set_major_formatter(KenFormatter(locator)) locator = KenLocator(7.8) self.axes.xaxis.set_major_locator(locator) self.axes.xaxis.set_major_formatter(KenFormatter(locator)) self.root.mainloop() def update_bounds(self, left, right, dragging=False): if not dragging: self.axes.set_xbound(to_ordinal(left), to_ordinal(right)) self.axes.set_xlabel(format_span(left, right) + " (" + format_timedelta(right - left) + ")") agg_canvas = self.nav_canvas.get_tk_widget() agg_canvas.delete("OVERLAY") # c1 c3 # +---+---------+---+ # |...| _/\ _ |...| # |...|/ \_/ \|...| # +---+---------+---+ # c2 c4 cx2, cy2 = self.nav_axes.transData.transform_point((to_ordinal(left), self.max_y)).tolist() cx3, cy3 = self.nav_axes.transData.transform_point((to_ordinal(right), self.min_y)).tolist() agg_canvas.create_rectangle([cx2, cy2, cx3, cy3], tags="OVERLAY", stipple = "gray50", fill = "green") ## cx1, cy1 = self.nav_axes.transData.transform_point((to_ordinal(self.slider.left_bound), self.min_y)).tolist() ## cx2, cy2 = self.nav_axes.transData.transform_point((to_ordinal(left), self.max_y)).tolist() ## agg_canvas.create_rectangle([(cx1+1, cy1+2), (cx2, cy2)], ## tags="OVERLAY", ## stipple="gray50", ## fill="red", outline="") ## ## cx3, cy3 = self.nav_axes.transData.transform_point((to_ordinal(right), self.min_y)).tolist() ## cx4, cy4 = self.nav_axes.transData.transform_point((to_ordinal(self.slider.right_bound), self.max_y)).tolist() ## agg_canvas.create_rectangle([(cx3, cy3+2), (cx4, cy4)], ## tags="OVERLAY", ## stipple="gray50", ## fill="red", outline="") if not dragging: self.figure.canvas.draw() self.nav_figure.canvas.draw() def select_interval(self, index=None): #Support direct invocation, invocation by event, and as a command if not isinstance(index, int): if not self.interval_picker.curselection(): return index = int(self.interval_picker.curselection()[0]) name, start, end = self.intervals[index] for identifier in self.data: view = self.data[identifier] view.load(start, end) self.collections[identifier].set_segments([view.export()]) self.collections[identifier].set_antialiased(False) self.nav_collections[identifier].set_segments([view.export()]) self.slider.config(left_bound=start, right_bound=end) self.slider.reset() self.nav_axes.set_xbound(to_ordinal(start), to_ordinal(end)) self.nav_axes.set_xlabel("%s (%s)" % (format_span(start, end), format_timedelta(end - start))) self.redraw() def toggle_source(self, desc, enabled): if desc.table_name in self.data: self.nav_collections[desc.table_name].set_visible(enabled) self.collections[desc.table_name].set_visible(enabled) self.redraw() elif enabled: self.axes.set_ylabel(desc.units) self.add_source(desc.table_name, desc.title) self.min_y = min(self.min_y, desc.min_y) self.max_y = max(self.max_y, desc.max_y) self.axes.set_ybound(self.min_y,self.max_y) self.nav_axes.set_ybound(self.min_y, self.max_y) ## self.axes.legend(loc=3) self.redraw() def redraw(self): self.figure.canvas.draw() self.nav_figure.canvas.draw() def add_source(self, identifier, title): left, right = sorted([self.slider.left_bound, self.slider.right_bound]) view = SQLIntervalView(self.connection, identifier, left, right) self.data[identifier] = view colors = [self.color_map.get(identifier, self.colors[0])] col = DatetimeCollection([view.export()], colors=colors) col.set_label(title) self.collections[identifier] = col col2 = DatetimeCollection([view.export()], colors=colors) self.nav_collections[identifier] = col2 self.axes.add_collection(col) self.nav_axes.add_collection(col2)