class MplCanvas(FigureCanvasQTAgg):
    def __init__(self,
                 parent=None,
                 width=5,
                 height=4,
                 dpi=100,
                 axes_h="X",
                 plot_type="Contour"):
        self.fig = Figure(figsize=(width, height),
                          constrained_layout=True,
                          dpi=dpi)
        self.create_axes(axes_h, plot_type)
        super(MplCanvas, self).__init__(self.fig)

    def update_axes(self, axes_h="X", plot_type="Contour"):
        self.create_axes(axes_h, plot_type)

    def create_axes(self, axes_h="X", plot_type="Contour"):
        if plot_type == "Contour":
            widths = [4.8, 0.2]
            spec = self.fig.add_gridspec(nrows=1, ncols=2, width_ratios=widths)
            self.ax_main = self.fig.add_subplot(spec[0, 0])
            self.ax_cbar = self.fig.add_subplot(spec[0, 1])
        elif plot_type in [
                "Contour+" + axes_h + "-Average",
                "Contour+" + axes_h + "-Slice"
        ]:
            widths = [0.2, 4.8, 1.2]
            spec = self.fig.add_gridspec(nrows=1,
                                         ncols=3,
                                         width_ratios=widths,
                                         wspace=0.0,
                                         hspace=0.0)
            self.ax_main = self.fig.add_subplot(spec[0, 1])
            self.ax1d = self.fig.add_subplot(spec[0, 2], sharey=self.ax_main)
            self.ax_cbar = self.fig.add_subplot(spec[0, 0])
        else:
            widths = [4.8, 0.2]
            heights = [4.8, 1.2]
            spec = self.fig.add_gridspec(nrows=2,
                                         ncols=2,
                                         width_ratios=widths,
                                         height_ratios=heights,
                                         wspace=0.0,
                                         hspace=0.0)
            self.ax_main = self.fig.add_subplot(spec[0, 0])
            self.ax_main.tick_params(axis='x', labelbottom=False)
            self.ax1d = self.fig.add_subplot(spec[1, 0], sharex=self.ax_main)
            self.ax_cbar = self.fig.add_subplot(spec[0, 1])
def plot_saliency_som_map(model, somdata, gradient, tube, channels):
    """Plot saliency and color channels as plots."""
    rgb = np.stack([
        get_channel_data(model, somdata, tube, channel)
        for channel in channels
    ], axis=-1)
    grad_max = np.max(get_channel_data(model, gradient, tube), axis=-1)

    fig = Figure()
    grid = fig.add_gridspec(3, 3, height_ratios=[1, 1, 0.1])
    ax_main = fig.add_subplot(grid[:2, :2])
    ax_main.imshow(plt_som.scale_weights_to_colors(rgb), interpolation="nearest")
    ax_main.set_axis_off()
    ax_main.imshow(grad_max, interpolation="nearest", alpha=0.60, cmap="gray")
    ax_main.set_title("Combined")
    patches = [
        mpl.patches.Patch(color=color, label=channel)
        for channel, color in zip(channels, ("red", "green", "blue"))
    ]
    ax_rgb = fig.add_subplot(grid[0, 2])
    ax_rgb.imshow(plt_som.scale_weights_to_colors(rgb), interpolation="nearest")
    ax_rgb.set_axis_off()
    ax_rgb.set_title("Channels")
    ax_mask = fig.add_subplot(grid[1, 2])
    ax_mask.imshow(grad_max, interpolation="nearest", cmap="gray")
    ax_mask.set_axis_off()
    ax_mask.set_title("Saliency")
    ax_legend = fig.add_subplot(grid[2, :])
    ax_legend.legend(handles=patches, framealpha=0.0, ncol=3, loc="center")
    ax_legend.set_axis_off()
    FigureCanvas(fig)
    fig.tight_layout()
    return fig
Exemple #3
0
    def plot(
        self,
        fig: Figure = None,
        **plt_kwargs
    ) -> None:
        """Plot the tree.

        Parameters
        ----------
        fig: matplotlib.figure.Figure
            A matplotlib Figure object.
        **plt_kwargs:
            Keywords plotting arguments

        """
        if fig is None:
            fig = plt.figure(constrained_layout=True, **plt_kwargs)
        gs = fig.add_gridspec(self.height, 2**self.height)

        row_idx = 0
        col_idx = 2**self.height // 2 - 1
        for node in self.tree:
            if node.identifier[0] > row_idx:
                row_idx += 1
                if node.identifier[1] == 0:
                    col_idx = 2**(self.height - row_idx) // 2 - 1
                else:
                    col_idx = 2**(node.identifier[1] + 1) + 1
            if not row_idx == (self.height - 1):
                ax = fig.add_subplot(gs[row_idx, col_idx:(col_idx + 2)])
                col_idx += 2**(self.height - row_idx)
            else:
                col_idx = 2 * node.identifier[1]
                ax = fig.add_subplot(gs[row_idx, col_idx:(col_idx + 2)])
            node.plot(axes=ax)
class PlotCanvas(FigureCanvas):
    """ Class for the matplotlib graph as a widget """
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        """ Constructor """
        self.fig = Figure(figsize=(width, height),
                          dpi=dpi,
                          constrained_layout=False)
        self.gs = self.fig.add_gridspec(1, 1, wspace=0.0, hspace=0.0)

        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
    def __init__(self, parent, controller, active_traps, maxima, pulse_widths, current, voltage, starts, ends):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text='Start Page', font=LARGE_FONT)
        label.pack(pady=10,padx=10)

        # NAVIGATION BUTTONS
        graph_button = tk.Button(self, text="Compare All Pulses", 
                            command = lambda: controller.show_frame(GraphPage))
        graph_button.pack()
        
        custom_button = tk.Button(self, text="Compare Select Pulses",
                                    command = lambda: controller.show_frame(CustomPage))
        custom_button.pack()

        f = Figure(figsize=(10,6))#, dpi=100)
        gs = f.add_gridspec(3, 2)

        a = f.add_subplot(gs[0, 0])
        a.scatter(active_traps,maxima)
        a.set_title('Peak Current vs Trap Number')
        a.set_xlabel('Trap Number')
        a.set_ylabel('Peak Curennt (A)')
        a.set_ylim([0,1.1*max(maxima)]) #1.1 for visibility

        b = f.add_subplot(gs[0,1])
        b.scatter(active_traps,pulse_widths+[0]*(len(active_traps)-len(pulse_widths)))
        b.set_title('Pulse Width vs Trap Number')
        b.set_xlabel('Trap Number')
        b.set_ylabel('Pulse Width (s)')
        b.set_ylim([0,1.1*max(pulse_widths)]) #1.1 for visibility

        c = f.add_subplot(gs[1,:])
        c.scatter(current['Time (s)'].apply(lambda x: x*1000*1000).to_list(),current['Current (A)'].to_list()) 
        c.set_title('Current vs Time')
        c.set_xlabel('Time (us)')
        c.set_ylabel('Current (A)')
        
        
        d = f.add_subplot(gs[2,:])
        d.scatter(voltage['Time (s)'].apply(lambda x: x*1000*1000).to_list(),voltage['Voltage (V)'].to_list())
        d.set_title('Voltage vs Time')
        d.set_xlabel('Time (us)')
        d.set_ylabel('Voltage (V)')

        f.tight_layout()

        canvas = FigureCanvasTkAgg(f, self)
        canvas.draw()
        canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)

        toolbar = NavigationToolbar2Tk(canvas, self)
        toolbar.update()
        canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
Exemple #6
0
class PlotCanvas(FigureCanvas):
    """ Plot canvas class used to make a matplotlib graph into a widget.
    """
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        """ Create the widget.
        """
        self.fig = Figure(figsize=(width, height),
                          dpi=dpi,
                          constrained_layout=False)
        self.gs = self.fig.add_gridspec(1, 1, wspace=0.0, hspace=0.0)

        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
Exemple #7
0
class PlotCanvas(FigureCanvas):
    """
    Provides basic plotting functionality
    """
    def __init__(self, parent=None, width=10, height=8, dpi=100):
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        self.fig.add_gridspec(5, 5)
        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
        self.dataset_plotting_list = []
        self.ax = self.fig.add_subplot(111)
        FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

    def plot(self, dataset):
        """
        Plots data with label for future implementation of legend
        """
        self.dataset_plotting_list.append(dataset)
        self.ax.plot(dataset.get_xvals(), dataset.get_yvals(), label=dataset.get_name())
        if len(self.dataset_plotting_list) >= 2:
            self.ax.legend(loc ='lower right')
        self.ax.grid()
        self.draw()
Exemple #8
0
def pie():
    fig = Figure()
    # axes = fig.subplots()
    langs = ['C', 'C++', 'Java', 'Python', 'PHP']
    students = [23, 17, 35, 29, 12]
    # axes.pie(students, labels = langs,autopct='%1.2f%%')

    gs = fig.add_gridspec(1, 1)
    ax1 = fig.add_subplot(gs[0, 0])
    ax1.pie(students, labels=langs, autopct='%1.2f%%')

    # Save it to a temporary buffer.
    buf = BytesIO()
    fig.savefig(buf, format="png")
    # Embed the result in the html output.
    data = base64.b64encode(buf.getbuffer()).decode("ascii")
    # return f"<img src='data:image/png;base64,{data}'/>"
    return render_template("charts/pie.html", pie=data)
Exemple #9
0
def plot_color_grid(griddata, channels, scale=True):
    """Plot array with 3 color channels as RGB values."""
    if scale:
        griddata = scale_weights_to_colors(griddata)

    fig = Figure()
    grid = fig.add_gridspec(2, 1, height_ratios=[1, 0.1])
    axes = fig.add_subplot(grid[0, 0])
    axes.imshow(griddata, interpolation="nearest")
    axes.set_axis_off()

    patches = [
        Patch(color=color, label=channel)
        for channel, color in zip(channels, ("red", "green", "blue"))
    ]

    ax_legend = fig.add_subplot(grid[1, 0])
    ax_legend.legend(handles=patches, framealpha=0.0, ncol=3, loc="center")
    ax_legend.set_axis_off()

    # Saving the figure
    FigureCanvas(fig)
    fig.tight_layout()
    return fig
Exemple #10
0
class QtMplPanel(FigureCanvas):
    def __init__(self, parent):
        self.fig = Figure()
        self. gs = self.fig.add_gridspec(2, 1)  # grid for Axes
        self.axe1 = self.fig.add_subplot(self.gs[0, 0])
        self.axe2 = self.fig.add_subplot(self.gs[1, 0])


        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
        # Containers
        self.data1 = []
        self.data2 = []
        self.data3 = []
        self.data4 = []

    def update_axe(self, number_of_block):
        self.axe1.clear()
        self.axe2.clear()

        self.axe1.plot(range(len(self.data1[number_of_block])), self.data1[number_of_block])
        self.axe2.plot(range(len(self.data2[number_of_block])), self.data2[number_of_block])

        self.fig.canvas.draw()
def visualize_eis_data(frame):

    eis_data_frame = tk.Toplevel(frame)
    eis_data_frame.title("EIS Data-Library")
    eis_data_frame.geometry("{}x{}".format(800, 600))
    eis_data_frame.maxsize(800, 600)
    eis_data_frame.config(bg="blue")
    eis_data_frame.iconbitmap('zbt_logo.ico')

    #eis_data_frame.rowconfigure(0, weight=1)

    #eis_data_frame.rowconfigure(1, weight=1)

    top_eis_data_frame = Frame(eis_data_frame,
                               bg='green',
                               width=800,
                               height=50)
    # bot_eis_data_frame = Frame(eis_data_frame, bg='grey', width=800, height=700)
    top_eis_data_frame.grid_propagate(0)
    # bot_eis_data_frame.grid_propagate(0)

    top_eis_data_frame.grid(row=0, column=2)
    # bot_eis_data_frame.grid(row=1)

    rootpath = pathlib.Path(__file__).parent.absolute()
    filelist = [
        fname[:-4]
        for fname in os.listdir(str(rootpath) + '/EIS_data/CSV_data/')
        if fname.endswith('.csv')
    ]

    # set startvalue and define optionmenu
    var = tk.StringVar(top_eis_data_frame)

    var.set(filelist[0])

    option = tk.OptionMenu(
        top_eis_data_frame,
        var,
        *filelist,
        command=lambda _: eis_plotter(var.get(), eis_canvas, fig_ax1))

    option.grid(row=0, column=0, sticky='ew', padx=(10, 10))
    #option.pack()

    fig = Figure(figsize=(50, 50))
    grid = fig.add_gridspec(13, 18)

    fig_ax1 = fig.add_subplot(grid[:13, :18])
    fig_ax1.set_title('EIS-Data Comparison',
                      pad=10,
                      fontdict=dict(fontsize=16, weight='bold'))

    # fig_ax1.set_xlim([0, 20])
    # fig_ax1.set_ylim([0, 400])

    eis_canvas = FigureCanvasTkAgg(fig, master=eis_data_frame)
    #eis_canvas.get_tk_widget().grid(row=1, column=0)

    #eis_canvas.get_tk_widget().pack()

    eis_data_frame.mainloop()
def create_archive():
    archive = tk.Toplevel(menu)
    archive.title('Archive')
    archive.geometry('2000x1000')
    archive.iconbitmap('zbt_logo.ico')

    # top = Frame(archive, bg='lightgrey', width=600, height=275)
    # top.grid_propagate(0)
    # bot = Frame(archive, bg='grey', width=600, height=25)
    # bot.grid_propagate(0)

    #top.grid_columnconfigure((0, 0), weight=1)
    # bot.grid_columnconfigure((0, 0), weight=1)

    # #read library and get names of measurements
    df_lib = pd.read_csv('cr_library.csv', delimiter='\t')
    measurement_name = df_lib['measurement'].unique()

    #set startvalue and define optionmenu
    var = tk.StringVar(archive)
    var.set(measurement_name[0])
    option = tk.OptionMenu(
        archive,
        var,
        *measurement_name,
        command=lambda _: plotter2(var.get(), df_lib, plot_canvas, fig_ax1,
                                   fig_ax2, fig_ax3, fig_ax4, fig_ax5))

    option.pack()

    varmr = '1'
    checkbutton1 = tk.Checkbutton(archive,
                                  text="Gesamtwiderstand",
                                  variable=varmr,
                                  onvalue="GW",
                                  offvalue="",
                                  bg='lightgrey')
    varfr = '2'
    checkbutton2 = tk.Checkbutton(archive,
                                  text="Durchgangswiderstand",
                                  variable=varfr,
                                  onvalue="DW",
                                  offvalue="",
                                  bg='lightgrey')
    varcr = '3'
    checkbutton3 = tk.Checkbutton(archive,
                                  text="Kontaktwiderstand",
                                  variable=varcr,
                                  onvalue="KW",
                                  offvalue="",
                                  bg='lightgrey')
    # checkbutton1.pack()
    # checkbutton2.pack()
    # checkbutton3.pack()

    fig = Figure(figsize=(50, 50))
    grid = fig.add_gridspec(13, 18)

    fig_ax1 = fig.add_subplot(grid[:13, :-8])
    fig_ax1.set_title('Durchgangswiderstand - Muster(1-6)',
                      pad=10,
                      fontdict=dict(fontsize=18, weight='bold'))
    # fig_ax1.text(0.05, -0.1, table_data, style='italic',
    #     bbox={'facecolor': 'blue', 'alpha': 0.5, 'pad': 10})

    #fig_ax1.table('test', cellColours='blue', bbox=[0.05, -0.1, 0.5, 0.2])
    fig_ax1.set_xlim([6, 30])
    fig_ax1.set_ylim([0, 400])

    fig_ax2 = fig.add_subplot(grid[1:6, 5:9])
    fig_ax2.set_title('Kontaktwiderstand @ 20bar',
                      fontdict=dict(fontsize=10, weight='bold'))

    fig_ax3 = fig.add_subplot(grid[0:3, 12:])
    fig_ax3.set_title('volumetrischer Gesamt-Leitwert [S/cm] @ 10bar',
                      pad=10,
                      fontdict=dict(fontsize=14, weight='bold'))

    fig_ax4 = fig.add_subplot(grid[5:8, 12:])
    fig_ax4.set_title('volumetrischer Durchgangs-Leitwert [S/cm] @ 10bar',
                      pad=10,
                      fontdict=dict(fontsize=14, weight='bold'))

    fig_ax5 = fig.add_subplot(grid[10:13, 12:])
    fig_ax5.set_title('volumetrischer Bulk-Leitwert [S/cm] @ 10bar',
                      pad=10,
                      fontdict=dict(fontsize=14, weight='bold'))

    # fig_ax6 = fig.add_subplot(grid[11:13, :-8])
    plot_canvas = FigureCanvasTkAgg(fig, master=archive)
    plot_canvas.get_tk_widget().pack()

    archive.mainloop()
Exemple #13
0
class ZoomCanvas(FigureCanvas):

    point_picked = Signal(object)

    def __init__(self, main_canvas, draw_crosshairs=True):
        self.figure = Figure()
        super().__init__(self.figure)

        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.main_canvas = main_canvas
        self.pv = main_canvas.iviewer.pv

        self.draw_crosshairs = draw_crosshairs

        self.axes = None
        self.axes_images = None
        self.frozen = False

        # Set up the box overlay lines
        ax = self.main_canvas.axis
        self.box_overlay_line = ax.plot([], [], 'm-')[0]
        self.crosshairs = None
        self.vhlines = None

        # user-specified ROI in degrees (from interactors)
        self.tth_tol = 0.5
        self.eta_tol = 10.0

        self.setup_connections()

    def setup_connections(self):
        self.mc_mne_id = self.main_canvas.mpl_connect(
            'motion_notify_event', self.main_canvas_mouse_moved)
        self.mne_id = self.mpl_connect('motion_notify_event',
                                       self.mouse_moved)
        self.bp_id = self.mpl_connect('button_press_event',
                                      self.button_pressed)

    def __del__(self):
        self.cleanup()

    def cleanup(self):
        self.disconnect()
        self.remove_overlay_lines()

    def disconnect(self):
        if self.mc_mne_id is not None:
            self.main_canvas.mpl_disconnect(self.mc_mne_id)
            self.mc_mne_id = None

        if self.mne_id is not None:
            self.mpl_disconnect(self.mne_id)
            self.mne_id = None

        if self.bp_id is not None:
            self.mpl_disconnect(self.bp_id)
            self.bp_id = None

    def remove_overlay_lines(self):
        if self.box_overlay_line is not None:
            self.box_overlay_line.remove()
            self.box_overlay_line = None

    def clear_crosshairs(self):
        if self.crosshairs is not None:
            self.crosshairs.set_data([], [])

    def remove_crosshairs(self):
        if self.crosshairs is not None:
            self.crosshairs.remove()
            self.crosshairs = None

    def button_pressed(self, event):
        if event.button != 1:
            # Don't do anything if it isn't a left click
            return

        self.point_picked.emit(event)

    def mouse_moved(self, event):
        # Clear the crosshairs when the mouse is moving over the canvas
        self.clear_crosshairs()
        self.update_vhlines(event)

        # Can't use draw_idle() since the Cursor has useblit=True
        self.draw()

    def update_vhlines(self, event):
        # These are vertical and horizontal lines on the integral axes
        if any(not x for x in [self.vhlines, self.axes]):
            return

        vline, hline = self.vhlines
        vline.set_xdata(event.xdata)
        hline.set_ydata(event.ydata)

    def main_canvas_mouse_moved(self, event):
        if event.inaxes is None:
            # Do nothing...
            return

        if not event.inaxes.get_images():
            # Image is over intensity plot. Do nothing...
            return

        if self.frozen:
            # Do not render if frozen
            return

        self.xdata = event.xdata
        self.ydata = event.ydata

        self.render()

    def plot_crosshairs(self, xlims, ylims):
        x_scale = 0.05
        y_scale = 0.05

        center = np.array([np.mean(xlims), np.mean(ylims)])

        xmag = abs(xlims[1] - xlims[0]) * x_scale
        ymag = abs(ylims[1] - ylims[0]) * y_scale

        vals = [
            center + (0, ymag),
            center - (0, ymag),
            (np.nan, np.nan),
            center + (xmag, 0),
            center - (xmag, 0)
        ]

        self.crosshairs.set_data(zip(*vals))

    def render(self):
        self.clear_crosshairs()

        point = (self.xdata, self.ydata)
        rsimg = self.main_canvas.iviewer.img
        _extent = self.main_canvas.iviewer._extent
        pv = self.pv

        roi_diff = (np.tile([self.tth_tol, self.eta_tol], (4, 1)) * 0.5 *
                    np.vstack([[-1, -1], [1, -1], [1, 1], [-1, 1]]))
        roi_deg = np.tile(point, (4, 1)) + roi_diff

        # Clip the values into the required boundaries
        roi_deg[:, 0] = np.clip(roi_deg[:, 0],
                                *np.degrees((pv.tth_min, pv.tth_max)))
        roi_deg[:, 1] = np.clip(roi_deg[:, 1],
                                *np.degrees((pv.eta_min, pv.eta_max)))

        # get pixel values from PolarView class
        i_row = pv.eta_to_pixel(np.radians(roi_deg[:, 1]))
        j_col = pv.tth_to_pixel(np.radians(roi_deg[:, 0]))

        # Convert to integers
        i_row = np.round(i_row).astype(int)
        j_col = np.round(j_col).astype(int)

        # plot
        roi = rsimg[i_row[1]:i_row[2], j_col[0]:j_col[1]]
        a2_data = (
            np.degrees(pv.angular_grid[1][0, j_col[0]:j_col[1]]),
            np.sum(roi, axis=0)
        )
        a3_data = (
            np.sum(roi, axis=1),
            np.degrees(pv.angular_grid[0][i_row[1]:i_row[2], 0])
        )

        xlims = roi_deg[0:2, 0]
        ylims = roi_deg[2:0:-1, 1]

        if self.axes_images is None:
            grid = self.figure.add_gridspec(5, 5)
            a1 = self.figure.add_subplot(grid[:4, :4])
            a2 = self.figure.add_subplot(grid[4, :4], sharex=a1)
            a3 = self.figure.add_subplot(grid[:4, 4], sharey=a1)
            a1.set_xlim(*xlims)
            a1.set_ylim(*ylims)
            im1 = a1.imshow(rsimg, extent=_extent, cmap=self.main_canvas.cmap,
                            norm=self.main_canvas.norm, picker=True,
                            interpolation='none')
            a1.axis('auto')
            a1.label_outer()
            a3.label_outer()
            a3.tick_params(labelbottom=True)  # Label bottom anyways for a3
            self.cursor = Cursor(a1, useblit=True, color='red', linewidth=1)
            im2, = a2.plot(a2_data[0], a2_data[1])
            im3, = a3.plot(a3_data[0], a3_data[1])
            self.figure.suptitle(r"ROI zoom")
            a2.set_xlabel(r"$2\theta$ [deg]")
            a2.set_ylabel(r"intensity")
            a1.set_ylabel(r"$\eta$ [deg]")
            a3.set_xlabel(r"intensity")
            self.crosshairs = a1.plot([], [], 'r-')[0]
            self.axes = [a1, a2, a3]
            self.axes_images = [im1, im2, im3]
            self.grid = grid

            # These are vertical and horizontal lines on the integral axes
            vline = a2.axvline(0, color='red', linewidth=1)
            hline = a3.axhline(0, color='red', linewidth=1)
            self.vhlines = [vline, hline]
        else:
            # Make sure we update the color map and norm each time
            self.axes_images[0].set_cmap(self.main_canvas.cmap)
            self.axes_images[0].set_norm(self.main_canvas.norm)

            self.axes[0].set_xlim(*xlims)
            self.axes[0].set_ylim(*ylims)
            self.axes_images[1].set_data(a2_data)
            self.axes_images[2].set_data(a3_data)

            self.axes[1].relim()
            self.axes[1].autoscale_view()
            self.axes[2].relim()
            self.axes[2].autoscale_view()

        if self.draw_crosshairs:
            self.plot_crosshairs(xlims, ylims)

        xs = np.append(roi_deg[:, 0], roi_deg[0, 0])
        ys = np.append(roi_deg[:, 1], roi_deg[0, 1])
        self.box_overlay_line.set_data(xs, ys)

        # Can't use draw_idle() since the Cursor has useblit=True
        self.main_canvas.draw()
        self.draw_idle()
    def update_plot(self, data):

        # python data object
        self.data = data

        # data is currently setup where members == rows
        member = self.data.members[0]  # get the first member

        # plot A
        plot_a_data = member.plot_a_data()
        plot_a_labels = member.plot_a_labels()
        plot_a_desc = member.plot_a_desc()

        # plot B
        plot_b_data = member.plot_b_data()
        plot_b_labels = member.plot_b_labels()
        plot_b_desc = member.plot_b_desc()

        # plot C
        plot_c_data = member.plot_c_data()
        plot_c_labels = member.plot_c_labels()
        plot_c_desc = member.plot_c_desc()

        # The instance
        fig = Figure(
            figsize=(7, 5),
            dpi=65,
            facecolor=(1, 1, 1),
            edgecolor=(0, 0, 0),
            tight_layout=True,
        )

        # create a grid for our layout
        widths = [3, 2, 1]
        heights = [1, 100]
        gs = fig.add_gridspec(2, 3, width_ratios=widths, height_ratios=heights)

        # Is the area onto which the figure is drawn (our backend)
        self.canvas = FigureCanvas(fig)

        # layout wrappers to contain this widget
        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.canvas)

        # add subplots using the grid
        sp1 = fig.add_subplot(gs[1, 0], )
        sp2 = fig.add_subplot(gs[1, 1], sharey=sp1)
        sp3 = fig.add_subplot(gs[1, 2], sharey=sp1)
        title = fig.add_subplot(gs[0, :])
        title.spines["bottom"].set_visible(False)
        title.axes.get_xaxis().set_visible(False)
        title.axes.get_yaxis().set_visible(False)

        # Hide some default matplotlib elements
        for sp in [sp1, sp2, sp3, title]:
            sp.spines["left"].set_visible(False)
            sp.spines["right"].set_visible(False)
            sp.spines["top"].set_visible(False)
            sp.get_yaxis().set_visible(False)
            sp.tick_params(width=0,
                           labelsize=12)  # ticks gone, text slightly bigger

        bar1, *_ = sp1.bar(plot_a_labels,
                           plot_a_data,
                           width=0.95,
                           color="#006595")
        bar2, *_ = sp2.bar(plot_b_labels,
                           plot_b_data,
                           width=0.95,
                           color="#6cb33f")

        line, *_ = sp1.plot(plot_a_labels,
                            plot_a_data,
                            linewidth=10,
                            zorder=10,
                            color="#a6217c")

        sp1.plot()

        # reorganize the data to arrays of single values
        stack_data = [[plot_c_data[0]], [plot_c_data[1]], [plot_c_data[2]]]

        # stack bottom
        p1 = sp3.bar(
            plot_c_labels,
            stack_data[0],
            width=0.95,
            color="#006595",
        )

        # stack mid
        p2 = sp3.bar(
            plot_c_labels,
            stack_data[1],
            bottom=stack_data[0],
            width=0.95,
            color="#6cb33f",
        )

        # stack top NOTE see how we add the bottom 2 stacks to get the starting place
        p3 = sp3.bar(
            plot_c_labels,
            stack_data[2],
            bottom=plot_c_data[1] + plot_c_data[0],
            width=0.95,
            color="#a6217c",
        )

        # helper func
        def add_text(sp, x, y, s, c="white"):
            sp.text(
                x=x,
                y=y,
                s=s,
                horizontalalignment="center",
                verticalalignment="center",
                color=c,
                weight="bold",
            )

        # helper func
        def gen_descs(sp, data, desc, custom_height=None, color="white"):
            for i in range(len(desc)):
                add_text(sp, i, data[i] / 2, desc[i], color)

        # add text to the first 2 bar charts
        gen_descs(sp=sp1, data=plot_a_data, desc=plot_a_desc)
        gen_descs(sp=sp2, data=plot_b_data, desc=plot_b_desc, color="white")

        h = [
            plot_c_data[0] / 2,
            plot_c_data[0] + (plot_c_data[1] / 2),
            plot_c_data[0] + plot_c_data[1] + plot_c_data[2] / 2,
        ]

        # add text the the stack plot
        add_text(sp3, 0, h[0], plot_c_desc[0])
        add_text(sp3, 0, h[1], plot_c_desc[1])
        add_text(sp3, 0, h[2], plot_c_desc[2])

        height_offset = -20

        # block of text
        title.text(
            x=0.095,
            y=height_offset,
            s=
            f"Index: {member.age} \nPrice: ${curr(member.earnings)} \nScore: {member.retire} \nFunds: {member.exp_payout} years",
            color="white",
            bbox=dict(facecolor="gray",
                      edgecolor="gray",
                      boxstyle="round,pad=2"),
            horizontalalignment="left",
            verticalalignment="center",
            size=14,
        )

        # block of text with round bounding box
        title.text(
            x=0.25,
            y=height_offset,
            s=
            f"Start With \nMX indexed annuity: \nOld Value: ${curr(member.ann_pen)} \nNew Value: ${curr(member.total_pay)}",
            color="white",
            bbox=dict(facecolor="gray",
                      edgecolor="gray",
                      boxstyle="round,pad=2"),
            horizontalalignment="left",
            verticalalignment="center",
            size=14,
        )

        # block of text with arrow
        title.text(
            x=0.42,
            y=height_offset,
            s=
            f"Starting ${curr(member.mem_get)}\nmore for \ncontributing ${curr(member.cont_more)}\neach year",
            color="white",
            bbox=dict(facecolor="gray",
                      edgecolor="gray",
                      boxstyle="round,pad=2"),
            horizontalalignment="left",
            verticalalignment="center",
            size=14,
        )

        # block of text with round bounding box
        title.text(
            x=0.63,
            y=height_offset,
            s=
            f"End With \nTDI and indexed benefit: \nAnnual Rate: ${curr(member.db_ann_pen)} \nTotal Payout: ${curr(member.db_tot_pay)}",
            color="white",
            bbox=dict(facecolor="gray",
                      edgecolor="gray",
                      boxstyle="round,pad=2"),
            horizontalalignment="left",
            verticalalignment="center",
            size=14,
        )

        self.canvas.draw()
Exemple #15
0
def add_elements():
    global sa, playing, segment_playing, txt, my_thread, listbox, selection_A, ax1, ax2, bg
    global selection_B, left_select, right_select, max_wpm, x_scale, words_inwin
    global words_inwin, left_sel, audiopos, zoom_in, constructed
    global time_axis, fig, fig2, canvas, canvas2, step_width, stream

    constructed = True

    #audioname = 'semi_files//data//grav1.wav'
    #textname = 'semi_files//data//grav1.txt'
    tmpfolder = 'semi_files//data//tempalign'
    sa = SegmentAligner(audioname, textname, tmpfolder)
    #%% read all the data
    n_frames = sa.audio.getnframes()
    sr = sa.audio.getframerate()
    time_axis = np.arange(0, n_frames / sr, 1 / sr)

    sa.audio.setpos(sa.audio_sel[0])
    #struct.unpack(str(2*n_frames) + 'B', sa.audio.readframes(n_frames))
    data_all = np.frombuffer(sa.audio.readframes(n_frames), dtype=np.int16)
    sa.audio.setpos(sa.audio_sel[0])

    playing = False
    segment_playing = False
    txt = None
    my_thread = None
    listbox = None
    selection_A = 0
    selection_B = time_axis[-1]
    left_select = False
    right_select = False
    max_wpm = 400  # 200 is realistic
    x_scale = 20
    words_inwin = round(x_scale * (max_wpm / 60))
    step_width = 5
    left_sel = 0
    audiopos = 0
    zoom_in = 1

    #% --- create the figure for the audioplot
    fig = Figure(figsize=(8.5, 1.5), dpi=100,
                 frameon=False)  #means 1 inch = 100 pixels

    gs = fig.add_gridspec(5, 1)
    fig.add_subplot(gs[0:3, 0])

    ax1 = fig.gca()
    ax1.plot(time_axis[0:-1:200],
             data_all[0:-1:200],
             '-',
             color='dimgray',
             lw=0.5)
    ax1.get_yaxis().set_ticks([])
    ax1.set_xlim([0, x_scale])  # this works in audio, if pos> half of time a

    # ax1.text(1, 0,"test",  fontsize = 6, bbox=dict(pad = 0, facecolor='red', lw = 0 ), animated=False)

    # fig.set_tight_layout(True)
    # fig.tight_layout()

    fig.tight_layout(pad=0.01, w_pad=0.01, h_pad=0.01)
    fig.add_subplot(212).plot(time_axis,
                              np.empty((len(time_axis), 1)),
                              color='dimgray',
                              lw=0.2)

    ax2 = fig.gca()
    ax2.get_yaxis().set_ticks([])
    ax2.get_xaxis().set_ticks([])
    ax2.set_ylim([0, 1])
    ax2.set_xlim([0, x_scale])
    canvas = FigureCanvasTkAgg(fig, master=root)

    canvas.draw()
    # canvas.flush_events()
    # lines = ax1.get_lines()
    # for line in lines:
    #     line.set_animated(True)
    #     fig.draw_artist(line)

    canvas.get_tk_widget().place(x=0, y=30, width=850, height=220)

    #% --- create the figure for the labelplot

    # fig2 = Figure(figsize = (8.5,0.5), dpi=100,frameon=False) #means 1 inch = 100 pixels
    # fig2.add_subplot(111).plot(time_axis, np.empty((len(time_axis),1))
    #                            , color = 'dimgray', lw = 0.2)
    # fig2.gca().get_yaxis().set_ticks([])
    # fig2.gca().get_xaxis().set_ticks([])
    # fig2.tight_layout(pad=0.1)
    # fig2.gca().set_ylim([0,1])
    # fig2.gca().set_xlim([0,x_scale]) # this works in audio, if pos> half of time a

    # canvas2 = FigureCanvasTkAgg(fig2, master = root)
    # canvas2.draw()
    # canvas2.get_tk_widget().place(x = 0, y = 180, width=850, height=150)

    # define the audio stream which also updates the xposition
    #frame_count = 1024

    p = pyaudio.PyAudio()

    stream = p.open(format=p.get_format_from_width(sa.audio.getsampwidth()),
                    channels=sa.audio.getnchannels(),
                    rate=sa.audio.getframerate(),
                    output=True,
                    stream_callback=callback,
                    start=False)

    canvas.mpl_connect('button_press_event', onclick)

    align_button = tk.Button(root, text="align", command=align)
    align_button.place(x=850, y=505, width=150, height=25)

    txt_update_button = tk.Button(root, text='update', command=txt_update)
    txt_update_button.place(x=0, y=505, width=50, height=25)

    txt = tk.Text(root,
                  wrap=tk.WORD,
                  bg='grey12',
                  fg='gold',
                  inactiveselectbackground="red",
                  selectbackground='red',
                  insertbackground='red')

    # replace this with a canvas!
    scroll = tk.Scrollbar(txt)
    scroll.pack(side=tk.RIGHT, fill=tk.Y)
    # Configure the scrollbars
    # scroll.config(command=txt.yview)

    txt['yscrollcommand'] = scroll.set

    txt.place(x=0, y=270, width=850, height=240)

    add_text()

    #text['yscrollcommand'] = scrollbar1.set

    #word_axis = np.arange(1/sr, len(time_axis)-1/sr, len(sa.all_aligned_words))

    #txt.tag_config(word[0], background="yellow", foreground="red")
    #for word in sa.all_aligned_words:
    #print(txt.index('testtag'))
    #print(txt.get("1.0","end" ))
    #print(txt.get("%d.%d" % (1, 3),"%d.%d" % (1, 8)))

    # Creating a Listbox and
    # attaching it to root window
    listbox = tk.Listbox(root, selectmode="extended")

    # Adding Listbox
    listbox.place(x=850, y=30, width=150, height=480)

    # Creating a Scrollbar and
    # attaching it to listbox
    scrollbar = tk.Scrollbar(listbox)

    # Adding Scrollbar to the right
    # side of root window
    scrollbar.pack(side=tk.RIGHT, fill=tk.BOTH)

    fill_listbox()

    # Attaching Listbox to Scrollbar
    # Since we need to have a vertical
    # scroll we use yscrollcommand
    listbox.config(yscrollcommand=scrollbar.set)

    # setting scrollbar command parameter
    # to listbox.yview method its yview because
    # we need to have a vertical view
    scrollbar.config(command=listbox.yview)

    if words_read:
        for ii in range(len(words_read)):
            if (words_read[ii][0] == sa.all_aligned_words[ii][0]) and (
                    words_read[ii][1] == sa.all_aligned_words[ii][1]):
                sa.all_aligned_words[ii] = words_read[ii]
        fill_listbox()
        draw_words()

    bg = canvas.copy_from_bbox(ax1.bbox)
Exemple #16
0
class vis:
    def __init__(self, root):
        self.last_data = [1]
        self.points = []
        self.decay = []
        self.plotting = False
        self.fig = Figure()
        gs = self.fig.add_gridspec(2, 3)
        self.ax1 = self.fig.add_subplot(gs[0, 0])
        self.ax2 = self.fig.add_subplot(gs[1, 0])
        self.ax3 = self.fig.add_subplot(gs[:, 1])
        self.ax4 = self.fig.add_subplot(gs[0, 2])

        self.graph = FigureCanvasTkAgg(self.fig, master=root)
        self.graph.get_tk_widget().pack(side="left", fill='both', expand=True)

    def set_last(self, data):
        self.last_data += data

    def add_point(self, point):
        self.points.append(point)

    def add_decay(self, point):
        self.decay.append(point)

    def plot_eyes(self, eyes, input):
        self.ax3.cla()
        self.ax3.grid()
        self.ax3.set_title("What the AI sees")

        self.ax3.imshow(eyes)

        self.ax4.cla()
        self.ax4.grid()
        self.ax4.set_title("Move History")
        self.ax4.hist(input,
                      color="red",
                      weights=np.zeros_like(input) + 100. / len(input))
        self.ax4.hist(self.last_data,
                      color="black",
                      alpha=0.15,
                      weights=np.zeros_like(self.last_data) +
                      100. / len(self.last_data))

        self.graph.draw()

    def plotter(self):
        self.ax1.cla()
        self.ax1.grid()
        self.ax1.set_title("Total Score")
        #self.ax1.set_xlabel("AI Number")
        #self.ax1.set_ylabel("Total Score")
        dpts = self.points
        self.ax1.scatter(range(len(dpts)), dpts)

        self.ax2.cla()
        self.ax2.grid()
        self.ax2.set_title("Epsilon")
        #self.ax2.set_xlabel("AI Number")
        #self.ax2.set_ylabel("Epsilon")
        dpts = self.decay
        self.ax2.plot(dpts, marker='o', color='blue')

        self.graph.draw()
Exemple #17
0
    def make_plot(self):
        if self.num_times > 0:
            try:
                self.canvas.get_tk_widget().destroy()
            except:
                pass
        fig = Figure(figsize=(12, 6))
        gs = fig.add_gridspec(3, 3)
        ax1 = fig.add_subplot(gs[0:2, :])
        ax2 = fig.add_subplot(gs[2, 0])
        ax3 = fig.add_subplot(gs[2, 1])
        ax4 = fig.add_subplot(gs[2, 2])

        ax1.set_title(self.current_time)
        if self.power_off == False:
            bins = np.linspace(np.min(self.all_temps), np.max(self.all_temps),
                               25)
            pos_temps = np.array(
                self.all_temps)[np.where(np.array(self.ids) < 10000)[0]]
            fid_temps = np.array(
                self.all_temps)[np.where(np.array(self.ids) > 10000)[0]]
            ax2.hist(pos_temps, bins=bins, label='Pos')
            ax2.hist(fid_temps, bins=bins, label='Fids')
            ax2.legend(prop={'size': 6})

        mt = [m.strftime("%H:%M:%S") for m in self.mt]
        ax3.plot(mt, self.pb_temps['PBOX_TEMP_SENSOR'], '-x', label='PBOX')
        ax3.plot(mt, self.pb_temps['FPP_TEMP_SENSOR_1'], '-x', label='FPP1')
        ax3.plot(mt, self.pb_temps['FPP_TEMP_SENSOR_2'], '-x', label='FPP2')
        ax3.plot(mt, self.pb_temps['FPP_TEMP_SENSOR_3'], '-x', label='FPP3')
        ax3.plot(mt, self.pb_temps['GXB_TEMP_SENSOR'], '-x', label='GXB')
        ax3.plot(mt, self.mean_temp, '-x', label='Mean POS')
        ax3.legend(prop={'size': 6})
        ax3.set_xticklabels(mt, rotation=45)

        ax4.plot(mt, self.adc_values['ADC2'], '-x', label='ADC2')
        ax4.plot(mt, self.adc_values['ADC3'], '-x', label='ADC3')
        ax4.plot(mt, self.adc_values['ADC1'], '-x', label='ADC1')
        ax4.plot(mt, self.adc_values['ADC4'], '-x', label='ADC4')
        ax4.plot(mt, self.adc_values['ADC0'], '-x', label='ADC0')
        ax4.legend(prop={'size': 6})
        ax4.set_xticklabels(mt, rotation=45)

        for i in range(len(self.hole_coords)):
            x = self.hole_coords[i][0]
            y = self.hole_coords[i][1]

            if i not in self.nons:
                ax1.plot(x, y, color='lightgrey', marker='o', zorder=-1)
                if i in self.fifs:
                    text = 'F' + str(i)
                    col = 'blue'
                elif i in self.gifs:
                    text = 'G' + str(i)
                    col = 'purple'
                else:
                    text = i
                    col = 'black'
                ax1.text(x - .1, y + 0.3, text, color=col, fontsize=6)

        self.hole = 1
        ax1.scatter(self.hole_coords[self.hole][0],
                    self.hole_coords[self.hole][1],
                    marker='*',
                    s=200,
                    color='gold')

        self.dev_list = self.pdf['CAN_ID'].tolist()
        self.hole_list = self.pdf['DEVICE_LOC'].tolist()
        self.dev_id_loc = dict(zip(self.dev_list, self.hole_list))

        if self.power_off == False:
            holes = []
            idx = []
            for i, e in enumerate(self.ids):
                try:
                    holes.append(self.dev_id_loc[e])
                    idx.append(i)
                except:
                    print('failed: ', e)
                    self.nons.append(e)
                    pass
            temps = np.array(self.all_temps)[np.array(idx)]

            x = []
            y = []
            idx2 = []
            for i, e in enumerate(holes):
                try:
                    x.append(self.hole_coords[int(e)][0])
                    y.append(self.hole_coords[int(e)][1])
                    idx2.append(i)
                except:
                    print('failed: ', new_ids[i])
                    self.nons.append(new_ids[i])
                    pass
            temps = temps[np.array(idx2)]
            x = np.array(x)
            y = np.array(y)

            sc = ax1.scatter(x, y, s=120, c=temps)
            self.cbar = plt.colorbar(sc, ax=ax1)
        self.canvas = FigureCanvasTkAgg(fig, master=root)
        self.canvas.get_tk_widget().pack(side=tk.TOP,
                                         fill=tk.BOTH,
                                         expand=True)
        self.canvas._tkcanvas.pack()

        fig.canvas.draw()
        self.canvas.draw()

        self.num_times += 1
Exemple #18
0
class PlotCanvas(FigureCanvas):
    """ class to hold a canvas with a matplotlib figure and two subplots for plotting data and residuals """
    def __init__(self, data, xlabel, ylabel):
        self.data = data  # contains the x, y and error data
        self.fitline = None  # contains the fitline if available
        self.residuals = None  # contains the residuals if available

        # setup the FigureCanvas
        self.fig = Figure()
        FigureCanvas.__init__(self, self.fig)
        FigureCanvas.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)  

        # init some statevars
        self.errorbox_patch = None  # to hold the patches for drawing errorboxes
        self.range_selector = None

        # create the figure and axes       
        gs = self.fig.add_gridspec(3, 1)  # define three rows and one column
        self.ax1 = self.fig.add_subplot(gs[0:2,0])  # ax1 holds the plot of the data and spans two rows
        self.ax2 = self.fig.add_subplot(gs[2,0], sharex=self.ax1)  # ax2 holds the plot of the residuals and spans one row
        self.ax1.grid()
        self.ax1.set_ylabel(ylabel)
        self.ax2.axhline(y=0, linestyle='--', color='black')    
        self.ax2.set_ylabel('residual')
        self.ax2.set_xlabel(xlabel)
        self.ax2.grid() 

        # create empty lines for the data, fit and residuals
        self.data_line, = self.ax1.plot([], [], color='k', marker='o', fillstyle='none', lw=0, label='data')
        self.fitted_line, = self.ax1.plot([], [], label='fitted curve', linestyle='-.', color='k', lw=1) 
        self.residual_line, = self.ax2.plot([],[], color='k', marker='.', lw=1)    
        self.ax1.legend()  

    def toggle_rangeselector(self):
        if self.range_selector is None:
            self.range_selector = RangeSelector(self.ax1, self.data.x)
            self.redraw()
        else:
            self.range_selector.__remove__()
            self.range_selector = None
            self.redraw()
    
    def get_range(self):
        if self.range_selector is None: return (-np.inf, np.inf)
        return self.range_selector.get_range()

    def update_plot(self):        
        # update the plotlines
        self.data_line.set_data(self.data.x, self.data.y) 
        if self.residuals is not None:
            self.residual_line.set_data(self.data.x, self.residuals)
        else:
            self.residual_line.set_data(self.data.x[0], 0)  # need one datapoint for autoscaling to work
        if self.fitline is not None: self.fitted_line.set_data(self.fitline[0], self.fitline[1])
        
        # update errorboxes
        if self.data.yerr is not None or self.data.xerr is not None:
            # remove any previous errorbar patch
            if self.errorbox_patch:
                self.ax1.patches.remove(self.errorbox_patch)
            

            # calculate new errorbar info, patch it in
            verts = []
            codes = []      
            if self.data.yerr is not None and self.data.xerr is not None:
                for (x, y, ey, ex) in zip(self.data.x, self.data.y, self.data.yerr, self.data.xerr):
                    verts.append((x, y+ey))
                    codes.append(Path.MOVETO)
                    verts.append((x, y-ey))
                    codes.append(Path.LINETO)
    
                    verts.append((x+ex, y))
                    codes.append(Path.MOVETO)
                    verts.append((x-ex, y))
                    codes.append(Path.LINETO)
                    
            elif self.data.yerr is not None:
                for (x, y, ey) in zip(self.data.x, self.data.y, self.data.yerr):
                    verts.append((x, y+ey))
                    codes.append(Path.MOVETO)
                    verts.append((x, y-ey))
                    codes.append(Path.LINETO)
            
            else:
                for (x, y, ex) in zip(self.data.x, self.data.y, self.data.xerr):
                    verts.append((x+ex, y))
                    codes.append(Path.MOVETO)
                    verts.append((x-ex, y))
                    codes.append(Path.LINETO)                
                    
                    
            barpath = Path(verts, codes)
            self.errorbox_patch = patches.PathPatch(barpath, lw=1, edgecolor='black', zorder=2)
            self.ax1.add_patch(self.errorbox_patch)

        # rescale the axis
        self.ax1.relim()
        self.ax1.autoscale()
        self.ax2.relim()
        self.ax2.autoscale()

        # make the min and max yscale limits of the residual plot equal
        ymax = max(np.abs(self.ax2.get_ylim()))
        self.ax2.set_ylim(-ymax, ymax)

        # draw the plot
        self.fig.tight_layout()
        self.redraw()    

    def redraw(self):
        self.fig.canvas.draw() 
Exemple #19
0
class StartPage(Frame):
    """ Tkinter based class for single frame upon which widgets
    such as buttons, check-buttons, and entry are used as a
    simple graphical user interface.
    """
    LARGE_FONT = ("Veranda", 12)

    def __init__(self, parent, controller):
        Frame.__init__(self, parent)

        # Instance variables with page/window info of current frame
        self.controller = controller
        self.window = parent

        # Instance variables for widgets showing/picking user's desired #
        # directory.                                                    #
        self.entry_frame = Frame(self.controller, relief="raised", height=15)
        self.entry_frame.pack(side="top",
                              anchor="nw",
                              padx=2,
                              pady=2,
                              fill="x")

        # -Event handler for displaying user's desired directory
        self.choice_display = Entry(self.entry_frame, width=105)

        self.xml_dir = StringVar(self.controller)
        self.xml_dir.set(getcwd())

        self.user_choice()

        # -Object that contains XML paths and file counts
        self.xml = GetXMLPath()

        # Instance variables for the CheckButton widgets #
        self.checkbox_frame = LabelFrame(self.controller,
                                         text="Boards",
                                         relief="sunken")
        self.checkbox_frame.pack(side="top",
                                 anchor="nw",
                                 padx=2,
                                 pady=2,
                                 fill="x")

        self.seq_list = [
            'SSP', 'XGRAD', 'YGRAD', 'ZGRAD', 'RHO1', 'RHO2', 'THETA1',
            'THETA2'
        ]

        # -Event handler for selecting desired boards
        self.board_options = CheckBar(self.checkbox_frame, picks=self.seq_list)
        self.show_options()

        # Instance variable for Scrollable frame widgets #
        self.canvas_frame = Frame(self.controller, relief="sunken")
        self.canvas_frame.pack(side="top",
                               anchor="nw",
                               padx=2,
                               pady=2,
                               fill="both",
                               expand=True)

        # -Instance variables for the figure to be populated
        params = SubplotParams(left=0.25, right=0.95, top=0.98, bottom=0.02)
        self.plot_fig = Figure(figsize=[14.0, 18.0],
                               subplotpars=params,
                               constrained_layout=False)

        self.plot_fig.subplots_adjust(hspace=1.0)

        # -Setup for changing the size of the axes in the plot
        widths = [1]
        heights = self.get_repeat_list([0.65], 8)
        self.plot_fig.add_gridspec(nrows=8,
                                   ncols=1,
                                   width_ratios=widths,
                                   height_ratios=heights)

        # -Instance variable for the frame with scrolling functionality
        self.canvas_body = Scrollable(self.canvas_frame, self.plot_fig)
        self.mpl_canvas = self.canvas_body.mpl_cnv

        # Instance variables for the widgets controlling the animation #
        self.control_frame = Frame(self.controller, relief="sunken")
        self.control_frame.pack(side="bottom", anchor="sw", fill="x")

        # -Instance variables for the displaying the current time-point
        # in the animation
        self.shot_info = StringVar(self.controller)
        self.shot_info.set("Shot #: ")
        self.show_shot_num = Label(self.control_frame,
                                   textvariable=self.shot_info)

        # -Instance variables for the animation and navigation of plots
        self.toolbar = NavTb2(self.mpl_canvas, self.control_frame)

        self.canvas_setup()
        self.animator = ShotAnimator(self.plot_fig)
        self.animator.step_up_button(self.control_frame)
        self.animator.stop_button(self.control_frame)
        self.animator.step_dwn_button(self.control_frame)
        self.show_shot_num.pack(side="right", anchor="sw", fill="x")

    @staticmethod
    def get_repeat_list(list_2_repeat, num_of_times):
        return [num for num in list_2_repeat for i in range(num_of_times)]

    def user_choice(self):
        # Clear the Entry widget
        self.choice_display.delete(first=0, last="end")

        # Event handler for selecting desired directory
        choice = Button(self.entry_frame,
                        text="Select directory",
                        command=lambda: self.file_name())
        choice.pack(side="left")

        self.choice_display.pack(side="top", fill="x", expand=True)

    def show_options(self):
        """Set in label for the check-box frame"""
        self.board_options.pack(side="left", expand=False)

    def canvas_setup(self):
        self.canvas_body.pack(side="top",
                              anchor="nw",
                              fill="both",
                              expand=True)
        self.toolbar.pack(side="left", anchor="sw", fill="x")
        self.toolbar.update()

    def choice_show(self):
        self.choice_display.insert(index=0, string=self.xml_dir.get())

    def file_name(self):
        # Store full path to chosen directory and display it
        self.xml_dir.set(get_file(self.window))
        self.choice_show()

        # Disable the ability to modify the input, extract information
        # from the directory and pass it to the other class objects
        self.choice_display.config(state="disable")
        self.get_info()
        self.checkbox_frame.after(10, self.update_checkbox())

    def get_info(self):
        self.xml.get_xml_list(self.xml_dir.get())
        self.get_waveforms(self.xml.xml_full_path, self.xml.stop_condition)

    def get_waveforms(self, xml_paths, shot_count):
        self.xml.waveforms.append(xml_root(xml_paths, shot_count))

    def update_checkbox(self):
        """Taking advantage of the order of executions
        in the events, this function passes information to
        objects of respective application components for
        starting and controlling the animation
        """
        self.board_options.xml_info["waveforms"] = self.xml.waveforms
        self.board_options.xml_info["xml_count"] = self.xml.stop_condition

        self.board_options.fig = self.plot_fig
        self.board_options.label_txt = self.shot_info
        self.board_options.shot_label = self.show_shot_num
        self.board_options.animator_obj = self.animator
        self.board_options.cnv = self.canvas_body.update_canvas

        self.show_shot_num.config(textvariable=self.shot_info.set(
            "Shot #: {0}/{1}".format(0, self.xml.stop_condition)))

        self.animator.label_txt = self.shot_info
        self.animator.shot_len = self.xml.stop_condition
        self.animator.shot_label = self.show_shot_num
        self.animator.frame_seq = self.animator.new_frame_seq()
        self.animator.step_up_dwn = PrevNextIterator(
            [x for x in self.animator.frame_seq])
Exemple #20
0
def pie_city():
    #cities = ['ha hoi', 'thanh pho ho chi minh', 'da nang']
    db = get_db()
    jobs_count = db.jobs_info.count()
    cities = db.jobs_info.distinct('city')
    city_job_data = []
    c = []
    num = []
    salary = []
    for city in cities:
        query = {"city": city}
        # print(city + '-' + str(db.jobs_info.find(query).count()/jobs_count))
        # if(db.jobs_info.find(query).count()/jobs_count > 0.05):
        city_job_data.append({
            'city': city,
            'num': db.jobs_info.find(query).count(),
        })
    for job in db.jobs_info.find():
        if (job["maxSalary"] != 0):
            salary.append(job["maxSalary"] / 1000000)
            # print(job["maxSalary"])
    sorted_data = sorted(city_job_data, key=lambda k: k['num'], reverse=True)
    for i in range(5):
        c.append(sorted_data[i]['city'])
        num.append(sorted_data[i]['num'])
    # Draw Chart
    # print(city_jobs_count)
    fig = Figure()
    gs = fig.add_gridspec(1, 1)
    ax1 = fig.add_subplot(gs[0, 0])
    ax1.set_title("5 tỉnh thành có số lương công việc nhiều nhất")
    # ax2 = fig.add_subplot(gs[1, 0])
    # ax3 = fig.add_subplot(gs[0, 1])
    # ax4 = fig.add_subplot(gs[1, 1])
    pie = ax1.pie(num, autopct='%1.3f%%')
    ax1.legend(pie[0], c, loc="lower right", bbox_to_anchor=(0.25, 0))
    # ax2.pie(city_jobs_count, labels = cities,autopct='%1.2f%%')
    # ax3.pie(city_jobs_count, labels = cities,autopct='%1.2f%%')
    # ax4.pie(city_jobs_count, labels = cities,autopct='%1.2f%%')
    # Save it to a temporary buffer.
    buf = BytesIO()
    fig.savefig(buf, format="png")
    # Embed the result in the html output.
    data = base64.b64encode(buf.getbuffer()).decode("ascii")
    # return f"<img src='data:image/png;base64,{data}'/>"
    fig2 = Figure()
    gs2 = fig2.add_gridspec(1, 1)
    ax2 = fig2.add_subplot(gs[0, 0])
    ax2.set_xlabel('Mức lương (triệu đồng)')
    ax2.set_ylabel('Số lượng công việc')
    ax2.set_title('Phân bố mức lương')
    # ax2 =fig2.add_subplot(gs[1, 0])
    # ax3 = fig2.add_subplot(gs[0, 1])
    # ax4 = fig2.add_subplot(gs[1, 1])
    hist = ax2.hist(salary, 80)
    # ax2.pie(city_jobs_count, labels = cities,autopct='%1.2f%%')
    # ax3.pie(city_jobs_count, labels = cities,autopct='%1.2f%%')
    # ax4.pie(city_jobs_count, labels = cities,autopct='%1.2f%%')
    # Save it to a temporary buffer.
    buf = BytesIO()
    fig2.savefig(buf, format="png")
    # Embed the result in the html output.
    data2 = base64.b64encode(buf.getbuffer()).decode("ascii")
    return render_template("charts/pie.html", pie=data, hist=data2)
Exemple #21
0
class Root(Tk):
    def __init__(self):
        super(Root, self).__init__()
        self.title('PEAUCELLIER LINKAGE')
        self.geometry('1280x720')
        self.resizable(0, 0)
        self.columnconfigure(1, weight=1)
        self.rowconfigure(2, weight=1)
        self.measure_state = False
        self.protocol("WM_DELETE_WINDOW", self.salirfichero)
        self.a_value = DoubleVar()
        self.a_value.set(2)
        self.b_value = DoubleVar()
        self.b_value.set(5)
        self.c_value = DoubleVar()
        self.c_value.set(2)
        self.a0_value = DoubleVar()
        self.a0_value.set(0)
        self.b0_value = DoubleVar()
        self.b0_value.set(22.3316)
        self.c0_value = DoubleVar()
        self.c0_value.set(0)
        self.r_value = DoubleVar()
        self.r_xtr = [1.01, 5]
        self.r_value.set(2)
        self.scale_factor = DoubleVar()
        self.scale_factor.set(1)
        self.j = 0
        self.xs = []
        self.ys = []
        self.alpha = []
        self.beta = []
        self.theta = []
        self.time = []
        self.ratio = 60
        self.theta_max = DoubleVar()
        self.theta_max.set(round(math.degrees(1.4455), 4))
        self.x_max = DoubleVar()
        self.x_max.set(5.25)
        self.y_max = DoubleVar()
        self.y_max.set(4.6301)
        self.t_max = 1.4455
        self.widgets()

    def points_pos(self):
        a = self.a_value.get()
        b = self.b_value.get()
        c = self.c_value.get()
        r = self.r_value.get()
        t0 = self.c0_value.get()
        t_max = math.acos(
            (b**2 + c**2 - r**2 - a**2 - 2 * b * c) / (2 * r * a))
        ymax = (b + c) * (a * sen(t_max)) / (b - c)
        xmax = ((b + c)**2 - ymax**2)**0.5
        self.x_max.set(round(xmax, 4))
        self.y_max.set(round(ymax, 4))
        self.t_max = t_max
        if abs(t0) > t_max:
            sgn = t0 / abs(t0)
            t0 = t_max * sgn * 1
        A = [0, 0]
        B = [r, 0]
        C = [r + a * cos(t0), a * sen(t0)]
        AC = norm(C)
        alpha = math.atan(C[1] / C[0])
        beta = math.acos((b**2 + AC**2 - c**2) / (2 * b * AC))
        D = [b * cos(alpha + beta), b * sen(alpha + beta)]
        E = [b * cos(alpha - beta), b * sen(alpha - beta)]
        AF = (b**2 - c**2) / AC
        F = [AF * cos(alpha), AF * sen(alpha)]

        r_min = max([a - b + c, b - c - a, c - b - a, a - b - c])
        r_max = b + c - a
        self.r_xtr = [r_min + 0.01, r_max - 0.01]
        self.points = np.around(np.array([A, B, C, D, E, F]), 4)
        self.a0_value.set(round(math.degrees(alpha), 4))
        self.b0_value.set(round(math.degrees(beta), 4))
        self.c0_value.set(round(math.degrees(t0), 4))
        self.theta_max.set(round(math.degrees(t_max), 4))
        self.alpha.append(alpha)
        self.beta.append(beta)
        self.theta.append(t0)
        self.alpha = self.alpha[-self.ratio:]
        self.beta = self.beta[-self.ratio:]
        self.theta = self.theta[-self.ratio:]

    def salirfichero(self):
        valor = messagebox.askquestion('Salir', '¿Desea cerrar la aplicacion?')
        if valor == 'yes':
            self.destroy()

    def animate(self, i):
        self.i = i
        try:
            a = self.a_value.get()
            b = self.b_value.get()
            c = self.c_value.get()
        except:
            a = 0
            b = 0
            c = 0

        p1 = np.linspace(-self.t_max, self.t_max, num=50)
        p_inv = np.flipud(p1)
        p2 = p_inv[1:-1]
        angle_list = np.concatenate((p1, p2), axis=0)
        if self.measure_state and a != 0 and b != 0 and c != 0:
            cont = self.i % 98
            if self.selected.get() == 2:
                angle = math.sin(self.i / 20) * (self.t_max) * 0.9
            elif self.selected.get() == 3:
                if cont == 0:
                    self.j = self.j + 1
                angle = angle_list[cont * (-1)**self.j]
            else:
                angle = math.sin(self.i / 20) * (self.t_max) * 0.9

            self.c0_value.set(angle)
            state = False
            try:
                self.points_pos()
                state = True
            except:
                state = False
            if state:

                self.r_scale.config(from_=self.r_xtr[0], to=self.r_xtr[1])
                self.ax.clear()
                self.ax2.clear()

                n = 1.1
                y = self.y_max.get() * n
                x = self.x_max.get() * n
                if 1.2 * x < 2 * y:
                    self.ax.set_ylim(-y, y)
                    self.ax.set_xlim(-y * 0.2, y * 1.8)
                else:
                    self.ax.set_ylim(-0.6 * x, 0.6 * x)
                    self.ax.set_xlim(-x * 0.2, x)

                point = np.transpose(self.points)
                x_data = point[0, :]
                y_data = point[1, :]
                self.ax.plot(x_data, y_data, 'o')

                text = ['A', 'B', 'C', 'D', 'E', 'F']
                for i in range(len(text)):
                    self.ax.text(x_data[i] + 0.3, y_data[i] + 0.3, text[i])

                angle_plot = ['α', 'β', 'θ']
                alpha = self.alpha[-1]
                alpha_array = np.linspace(0, alpha, num=20)
                beta = self.beta[-1]
                beta_array = np.linspace(alpha, alpha + beta, num=20)
                theta = self.theta[-1]
                theta_array = np.linspace(0, theta, num=20)
                AD = norm([x_data[3], y_data[3]])
                BC = norm([x_data[2] - x_data[1], y_data[2] - y_data[1]])
                self.ax.text(AD * 0.3 * math.cos(alpha * 0.5),
                             AD * 0.3 * math.sin(alpha * 0.5), angle_plot[0])
                self.ax.plot(AD * 0.3 * np.cos(alpha_array),
                             AD * 0.3 * np.sin(alpha_array), 'b')
                self.ax.text(AD * 0.5 * math.cos(alpha + beta * 0.5),
                             AD * 0.5 * math.sin(alpha + beta * 0.5),
                             angle_plot[1])
                self.ax.plot(AD * 0.5 * np.cos(beta_array),
                             AD * 0.5 * np.sin(beta_array), 'r')
                self.ax.text(
                    BC * 0.5 * math.cos(theta * 0.5) + x_data[1] * 1.1,
                    BC * 0.5 * math.sin(theta * 0.5), angle_plot[2])
                self.ax.plot(BC * 0.5 * np.cos(theta_array) + x_data[1],
                             BC * 0.5 * np.sin(theta_array), 'g')

                data_lines = [[0, 1, 'k'], [0, 3, 'r'], [0, 4,
                                                         'r'], [1, 2, 'b'],
                              [2, 3, 'g'], [2, 4, 'g'], [3, 5, 'g'],
                              [4, 5, 'g'], [0, 5, '--']]
                for i, j, k in data_lines:
                    self.ax.plot([x_data[i], x_data[j]],
                                 [y_data[i], y_data[j]], k)

                self.time.append(self.i / 20)
                self.xs.append(x_data[5])
                self.ys.append(y_data[5])
                self.xs = self.xs[-self.ratio:]
                self.ys = self.ys[-self.ratio:]
                self.time = self.time[-self.ratio:]
                xs2 = np.array(self.xs)
                ys2 = np.array(self.ys)
                time = np.array(self.time)
                xs = np.array(self.xs[-15:])
                ys = np.array(self.ys[-15:])
                self.ax.plot(xs, ys, 'c.', alpha=0.5)
                alpha = np.array(self.alpha)
                beta = np.array(self.beta)
                theta = np.array(self.theta)
                try:
                    scale = self.scale_factor.get()
                except:
                    scale = 1
                if scale == 0:
                    scale = 1
                if len(self.xs) > 3:
                    w_a = np.gradient(alpha)
                    a_a = np.gradient(w_a)
                    w_b = np.gradient(beta)
                    a_b = np.gradient(w_b)
                    w_t = np.gradient(theta)
                    a_t = np.gradient(w_t)
                    dx = np.gradient(xs2)
                    dy = np.gradient(ys2)
                    d2x = np.gradient(dx)
                    d2y = np.gradient(dy)
                    vF = norm([dx, dy])
                    aF = norm([d2x, d2y])
                    v = [xs[-1] - xs[-2], ys[-1] - ys[-2]]
                    self.ax.quiver(xs[-1],
                                   ys[-1],
                                   v[0],
                                   v[1],
                                   angles='xy',
                                   scale_units='xy',
                                   scale=0.08,
                                   color='blue')
                    a = [
                        xs[-1] + xs[-3] - xs[-2] * 2,
                        ys[-1] + ys[-3] - ys[-2] * 2
                    ]
                    self.ax.quiver(xs[-1],
                                   ys[-1],
                                   a[0],
                                   a[1],
                                   angles='xy',
                                   scale_units='xy',
                                   scale=0.008,
                                   color='red')
                    coef = list(map(lambda x: x.get(), self.var_data))
                    values = [
                        alpha, beta, theta, w_a, a_a, w_b, a_b, w_t, a_t, vF,
                        aF
                    ]
                    cn = colors.Normalize(0, 11)
                    for i in range(11):
                        if coef[i] == 1:
                            if self.selected.get() == 1:
                                lim = self.t_max
                                self.ax2.set_ylim(-lim * 0.5 / scale,
                                                  lim * 0.5 / scale)
                                self.ax2.set_xlim(-lim, lim)
                                self.ax2.plot(self.theta,
                                              values[i],
                                              color=plt.cm.jet(cn(i)))
                            elif self.selected.get() == 2 or self.selected.get(
                            ) == 3:
                                lim = self.t_max
                                self.ax2.set_ylim(-self.t_max / scale,
                                                  self.t_max / scale)
                                self.ax2.set_xlim(time.min(), time.max())
                                self.ax2.plot(time,
                                              values[i] * scale,
                                              color=plt.cm.jet(cn(i)))

                self.ax.grid(True)
                self.ax2.grid(True)
                self.i = self.i + 1

    def state(self):
        if (self.measure_button['text'] == 'START'):
            self.measure_button['text'] = 'STOP'
            self.measure_state = True
        else:
            self.measure_button['text'] = 'START'
            self.measure_state = False

    def widgets(self):

        title = Label(self, text='PEAUCELLIER LINKAGE ANALISYS')
        title.place(x=300, y=10)
        title.config(justify='center', font=("Courier", 30))

        data_label = Label(self,
                           text='Input data: ',
                           font=("Times", 15, "italic"))
        data_label.place(x=75, y=75)
        a_label = Label(self, text='a: ', font=("Times", 15, "italic"))
        a_label.place(x=75, y=115)
        a_entry = Entry(self, textvariable=self.a_value)
        a_entry.place(x=100, y=120)
        a_color = Label(self, bg='blue', width=2)
        a_color.place(x=230, y=120)
        b_label = Label(self, text='b: ', font=("Times", 15, "italic"))
        b_label.place(x=75, y=145)
        b_entry = Entry(self, textvariable=self.b_value)
        b_entry.place(x=100, y=150)
        b_color = Label(self, bg='red', width=2)
        b_color.place(x=230, y=150)
        c_label = Label(self, text='c: ', font=("Times", 15, "italic"))
        c_label.place(x=75, y=175)
        c_entry = Entry(self, textvariable=self.c_value)
        c_entry.place(x=100, y=180)
        c_color = Label(self, bg='green', width=2)
        c_color.place(x=230, y=180)

        r_label = Label(self, text='r: ', font=("Times", 15, "italic"))
        r_label.place(x=270, y=135)
        self.r_scale = Scale(self,
                             variable=self.r_value,
                             from_=self.r_xtr[0],
                             to=self.r_xtr[1],
                             orient=HORIZONTAL,
                             length=200,
                             resolution=0.01)
        self.r_scale.place(x=315, y=125)

        data_label = Label(self,
                           text='Output data: ',
                           font=("Times", 15, "italic"))
        data_label.place(x=775, y=75)
        a0_label = Label(self, text='α: ', font=("Times", 15, "italic"))
        a0_label.place(x=775, y=115)
        a1_label = Label(self,
                         textvariable=self.a0_value,
                         font=("Times", 15, "italic"))
        a1_label.place(x=800, y=115)
        b0_label = Label(self, text='β: ', font=("Times", 15, "italic"))
        b0_label.place(x=775, y=145)
        b1_label = Label(self,
                         textvariable=self.b0_value,
                         font=("Times", 15, "italic"))
        b1_label.place(x=800, y=145)
        c0_label = Label(self, text='θ: ', font=("Times", 15, "italic"))
        c0_label.place(x=775, y=175)
        b1_label = Label(self,
                         textvariable=self.c0_value,
                         font=("Times", 15, "italic"))
        b1_label.place(x=800, y=175)
        m0_label = Label(self, text='θ_max: ', font=("Times", 15, "italic"))
        m0_label.place(x=975, y=115)
        m1_label = Label(self,
                         textvariable=self.theta_max,
                         font=("Times", 15, "italic"))
        m1_label.place(x=1050, y=115)
        y0_label = Label(self, text='y_max: ', font=("Times", 15, "italic"))
        y0_label.place(x=975, y=145)
        y1_label = Label(self,
                         textvariable=self.y_max,
                         font=("Times", 15, "italic"))
        y1_label.place(x=1050, y=145)
        x0_label = Label(self, text='x_max: ', font=("Times", 15, "italic"))
        x0_label.place(x=975, y=175)
        x1_label = Label(self,
                         textvariable=self.x_max,
                         font=("Times", 15, "italic"))
        x1_label.place(x=1050, y=175)
        scale_label = Label(self,
                            text='scale factor:',
                            font=("Times", 15, "italic"))
        scale_label.place(x=800, y=220)
        scale_entry = Entry(self, textvariable=self.scale_factor)
        scale_entry.place(x=920, y=225)

        self.measure_button = Button(self, text='START', command=self.state)
        self.measure_button.place(x=50, y=250)

        self.var_data = []
        self.var_text = [
            'α', 'β', 'θ', 'w_α', 'α_α', 'w_β', 'α_β', 'w_θ', 'α_θ', 'v', 'a'
        ]
        for i in range(len(self.var_text)):
            self.var_data.append(IntVar())
            Checkbutton(self,
                        text=self.var_text[i],
                        variable=self.var_data[-1]).place(x=570, y=80 + i * 20)

        self.selected = IntVar()
        Radiobutton(self, text='θ', value=1,
                    variable=self.selected).place(x=650, y=80)
        Radiobutton(self, text='t ∿', value=2,
                    variable=self.selected).place(x=650, y=100)
        Radiobutton(self, text='t ʌ', value=3,
                    variable=self.selected).place(x=650, y=120)

        self.fig = Figure(figsize=(14, 4), dpi=100)
        self.canvas = FigureCanvasTkAgg(self.fig, master=self)
        self.canvas.get_tk_widget().place(x=-100, y=300)
        gs = self.fig.add_gridspec(1, 3)
        self.ax = self.fig.add_subplot(gs[0, 0])
        self.ax2 = self.fig.add_subplot(gs[0, 1:])
        self.measure_state = True
        self.animate(0)
        self.measure_state = False
Exemple #22
0
import matplotlib.pyplot as plt
import cv2

if __name__ == "__main__":

    target_image = sys.argv[1]

    app = QtWidgets.QApplication(sys.argv)
    wid = QtWidgets.QWidget()
    wid.resize(250, 150)
    grid = QtWidgets.QVBoxLayout(wid)
    fig = Figure(figsize=(7, 5),
                 dpi=65,
                 facecolor=(1, 1, 1),
                 edgecolor=(0, 0, 0))
    gs = fig.add_gridspec(1, 1)
    ax = fig.add_subplot(gs[0, 0])
    # d = np.array([[i+j for i in range(-5, 6)] for j in range(-5, 6)])
    d = cv2.imread(target_image)
    im = ax.imshow(d[:, :, [2, 1, 0]])

    canvas = FigureCanvas(fig)
    toolbar = NavigationToolbar(canvas, None)
    grid.addWidget(canvas)
    grid.addWidget(toolbar)

    # Mouse tooltip
    from PySide2 import QtGui, QtCore, QtWidgets
    mouse_tooltip = QtWidgets.QLabel()
    mouse_tooltip.setFrameShape(QtWidgets.QFrame.StyledPanel)
    mouse_tooltip.setWindowFlags(QtCore.Qt.ToolTip)
Exemple #23
0
class ZoomCanvas(FigureCanvas):
    def __init__(self, main_canvas):
        self.figure = Figure()
        super(FigureCanvas, self).__init__(self.figure)

        self.main_canvas = main_canvas
        self.pv = main_canvas.iviewer.pv

        self.axes_images = None

        # Set up the box overlay lines
        ax = self.main_canvas.axis
        self.box_overlay_line = ax.plot([], [], 'm-')[0]

        # user-specified ROI in degrees (from interactors)
        self.tth_tol = 0.5
        self.eta_tol = 10.0

        self.setup_connections()

    def setup_connections(self):
        self.mne_id = self.main_canvas.mpl_connect('motion_notify_event',
                                                   self.mouse_moved)

    def __del__(self):
        self.cleanup()

    def cleanup(self):
        self.disconnect()
        self.remove_overlay_lines()

    def disconnect(self):
        if self.mne_id is not None:
            self.main_canvas.mpl_disconnect(self.mne_id)
            self.mne_id = None

    def remove_overlay_lines(self):
        self.box_overlay_line.remove()
        self.box_overlay_line = None

    def mouse_moved(self, event):
        if event.inaxes is None:
            # Do nothing...
            return

        if not event.inaxes.get_images():
            # Image is over intensity plot. Do nothing...
            return

        self.xdata = event.xdata
        self.ydata = event.ydata

        self.render()

    def render(self):
        point = (self.xdata, self.ydata)
        rsimg = self.main_canvas.iviewer.img
        _extent = self.main_canvas.iviewer._extent
        pv = self.pv

        roi_diff = (np.tile([self.tth_tol, self.eta_tol], (4, 1)) * 0.5 *
                    np.vstack([[-1, -1], [1, -1], [1, 1], [-1, 1]]))
        roi_deg = np.tile(point, (4, 1)) + roi_diff

        # Clip the values into the required boundaries
        roi_deg[:, 0] = np.clip(roi_deg[:, 0],
                                *np.degrees((pv.tth_min, pv.tth_max)))
        roi_deg[:, 1] = np.clip(roi_deg[:, 1],
                                *np.degrees((pv.eta_min, pv.eta_max)))

        # get pixel values from PolarView class
        i_row = pv.eta_to_pixel(np.radians(roi_deg[:, 1]))
        j_col = pv.tth_to_pixel(np.radians(roi_deg[:, 0]))

        # Convert to intgers
        i_row = np.round(i_row).astype(int)
        j_col = np.round(j_col).astype(int)

        # plot
        roi = rsimg[i_row[1]:i_row[2], j_col[0]:j_col[1]]
        a2_data = (np.degrees(pv.angular_grid[1][0, j_col[0]:j_col[1]]),
                   np.sum(roi, axis=0))

        xlims = roi_deg[0:2, 0]
        ylims = roi_deg[2:0:-1, 1]

        if self.axes_images is None:
            grid = self.figure.add_gridspec(3, 1)
            a1 = self.figure.add_subplot(grid[:2, 0])
            a2 = self.figure.add_subplot(grid[2, 0], sharex=a1)
            a1.set_xlim(*xlims)
            a1.set_ylim(*ylims)
            im1 = a1.imshow(rsimg,
                            extent=_extent,
                            cmap=self.main_canvas.cmap,
                            norm=self.main_canvas.norm,
                            picker=True,
                            interpolation='none')
            a1.axis('auto')
            a1.label_outer()
            im2, = a2.plot(a2_data[0], a2_data[1])
            self.figure.suptitle(r"ROI zoom")
            a2.set_xlabel(r"$2\theta$ [deg]")
            a2.set_ylabel(r"intensity")
            a1.set_ylabel(r"$\eta$ [deg]")
            self.axes = [a1, a2]
            self.axes_images = [im1, im2]
            self.grid = grid
        else:
            self.axes[0].set_xlim(*xlims)
            self.axes[0].set_ylim(*ylims)
            self.axes_images[1].set_data(a2_data)

            self.axes[1].relim()
            self.axes[1].autoscale_view(scalex=False)

        xs = np.append(roi_deg[:, 0], roi_deg[0, 0])
        ys = np.append(roi_deg[:, 1], roi_deg[0, 1])
        self.box_overlay_line.set_data(xs, ys)

        self.main_canvas.draw()
        self.draw()
Exemple #24
0
class _PlotCanvas(FigureCanvas):
    def __init__(self, parent=None):
        self.fig = Figure()
        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
        FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding,
                                   QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)
        self.plot()
        self.createConn()

        self.figureActive = False
        self.axesActive = None
        self.CPactive = None
        self.pickmode = False
        self.pickMode_changed = True
        self.cpChanged = False
        self.cursorGUI = 'arrow'
        self.cursorChanged = False
        self.CPlist = []
        self.lastIDP = 0

    def plot(self):
        gs0 = self.fig.add_gridspec(1, 2)

        self.ax11 = self.fig.add_subplot(
            gs0[0],
            xticks=[],
            yticks=[],
            title='Image 1: select Control Points')
        self.ax12 = self.fig.add_subplot(
            gs0[1],
            xticks=[],
            yticks=[],
            title='Image 2: select Control Points')

        self.ax11.imshow(img1)
        self.ax12.imshow(img2)

    def updateCanvas(self, event=None):
        ax11_xlim = self.ax11.get_xlim()
        ax11_xvis = ax11_xlim[1] - ax11_xlim[0]
        ax12_xlim = self.ax12.get_xlim()
        ax12_xvis = ax12_xlim[1] - ax12_xlim[0]

        while len(self.ax11.patches) > 0:
            [p.remove() for p in self.ax11.patches]
        while len(self.ax12.patches) > 0:
            [p.remove() for p in self.ax12.patches]
        while len(self.ax11.texts) > 0:
            [t.remove() for t in self.ax11.texts]
        while len(self.ax12.texts) > 0:
            [t.remove() for t in self.ax12.texts]

        ax11_units = ax11_xvis * 0.003
        ax12_units = ax12_xvis * 0.003

        for cp in self.CPlist:
            x1 = cp.img1x
            y1 = cp.img1y
            x2 = cp.img2x
            y2 = cp.img2y
            idp = str(cp.idp)

            if x1:
                symb1 = plt.Circle((x1, y1),
                                   ax11_units * 8,
                                   fill=False,
                                   color='red')
                symb2 = plt.Circle((x1, y1),
                                   ax11_units * 1,
                                   fill=True,
                                   color='red')
                self.ax11.text(x1 + ax11_units * 5, y1 + ax11_units * 5, idp)
                self.ax11.add_patch(symb1)
                self.ax11.add_patch(symb2)

            if x2:
                symb1 = plt.Circle((x2, y2),
                                   ax12_units * 8,
                                   fill=False,
                                   color='red')
                symb2 = plt.Circle((x2, y2),
                                   ax12_units * 1,
                                   fill=True,
                                   color='red')
                self.ax12.text(x2 + ax12_units * 5, y2 + ax12_units * 5, idp)
                self.ax12.add_patch(symb1)
                self.ax12.add_patch(symb2)

        self.fig.canvas.draw()

    def createConn(self):
        self.fig.canvas.mpl_connect('figure_enter_event', self.activeFigure)
        self.fig.canvas.mpl_connect('figure_leave_event', self.leftFigure)
        self.fig.canvas.mpl_connect('axes_enter_event', self.activeAxes)
        self.fig.canvas.mpl_connect('button_press_event', self.mouseClicked)
        self.ax11.callbacks.connect('xlim_changed', self.updateCanvas)
        self.ax12.callbacks.connect('xlim_changed', self.updateCanvas)

    def activeFigure(self, event):

        self.figureActive = True
        if self.pickmode and self.cursorGUI != 'cross':
            self.cursorGUI = 'cross'
            self.cursorChanged = True

    def leftFigure(self, event):

        self.figureActive = False
        if self.cursorGUI != 'arrow':
            self.cursorGUI = 'arrow'
            self.cursorChanged = True

    def activeAxes(self, event):
        self.axesActive = event.inaxes

    def mouseClicked(self, event):
        x = event.xdata
        y = event.ydata

        if self.toolbar.mode != '':
            self.pickmode = False

        if self.pickmode and (event.inaxes == self.ax11
                              or event.inaxes == self.ax12):

            if self.CPactive and not self.CPactive.status_complete:
                self.CPactive.appendCoord(x, y)
                self.cpChanged = True
            else:
                idp = self.lastIDP + 1
                cp = _ControlPoint(idp, x, y, self)
                self.CPlist.append(cp)
                self.cpChanged = True
                self.lastIDP += 1

            self.updateCanvas()
Exemple #25
0
class MatplotlibCanvas(FigureCanvas):
    """
    This is the matplotlib plot inside that controls all the visuals.
    Subplots are placed in a grid of nrows, ncols, and a position
    e.g. (131) means 1 row, 3 columns, position 1 (going from top left).
    """
    def __init__(
        self,
        ax_type,
        parent=None,
        width=6,
        height=2,
        dpi=100,
    ):
        self.fig = Figure(
            figsize=(width, height),
            dpi=dpi,
        )
        self.fig.set_facecolor(gvars.color_gui_bg)
        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
        self.defaultImageName = "Blank"  # Set default image name
        FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding,
                                   QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

        self.ax_type = ax_type

        if ax_type == "img":
            self.setupTwoColorImageLayout()
        elif ax_type == "trace":
            self.setupTwoColorTraceLayout()
        elif ax_type == "plot":
            self.setupSinglePlotLayout()
        elif ax_type == "histwin":
            self.setupHistogramWindowPlot()
        elif ax_type == "dynamic":
            self.setupDynamicPlotLayout()
        else:
            raise ValueError("Invalid ax_type")

    @staticmethod
    def adjust_margins(fig, margin=None, **kwargs):
        """
        Adjusts all margins if set to value, else individual elements
        can be controlled as usual
        """
        if type(fig) == GridSpec:
            fig.adjust = fig.update
        elif type(fig) == Figure:
            fig.adjust = fig.subplots_adjust
        else:
            raise ValueError("Invalid figure type")

        if margin is not None:
            fig.adjust(left=margin,
                       right=1 - margin,
                       top=1 - margin,
                       bottom=margin,
                       **kwargs)
        else:
            fig.adjust(**kwargs)

    @staticmethod
    def setupJointGrid(f: Figure, gs: GridSpecFromSubplotSpec):
        """
        Sets up JointGrid Setup as in Seaborn, from existing GridSpec.
        :param f: Figure to plot axes on
        :param gs: GridSpec to use. Should be square
        :return axes: Tuple of Axes, order center, top, right
        Example:
        for a 4x4 GridSpec, the three axes will be distributed as:
        tttx
        cccr
        cccr
        cccr
        where t is the top, c is center, and r is right axis
        """
        ax_ctr = f.add_subplot(gs[1:, :-1])
        ax_rgt = f.add_subplot(gs[1:, -1], sharey=ax_ctr)
        ax_top = f.add_subplot(gs[0, :-1], sharex=ax_ctr)

        return ax_ctr, ax_top, ax_rgt

    def setupHistogramWindowPlot(self):
        """
        Sets up plot for HistogramWindow using nested GridSpec.
        Outer grid is a 2x2 grid, and the inner grids are from top left, clockwise:
        6x6, 6x6, 2x1, 1x1
        """
        # outer_grid = GridSpec(nrows=1, ncols=1, figure=self.fig,)  # 2x2 grid
        # self.adjust_margins(
        #     fig=outer_grid, margin=0.10, hspace=0.10, wspace=0.10,
        # )
        #
        # gs_top_lft = GridSpecFromSubplotSpec(
        #     nrows=1, ncols=1, subplot_spec=outer_grid[0, 0], wspace=0, hspace=0,
        # )
        #
        # gs_top_rgt = GridSpecFromSubplotSpec(
        #     nrows=6, ncols=6, subplot_spec=outer_grid[0, 1], wspace=0, hspace=0,
        # )
        #
        # gs_btm_lft = GridSpecFromSubplotSpec(
        #     nrows=2,
        #     ncols=1,
        #     subplot_spec=outer_grid[1, 0],
        #     wspace=0,
        #     hspace=0.15,
        # )
        # gs_btm_rgt = GridSpecFromSubplotSpec(
        #     nrows=1, ncols=1, subplot_spec=outer_grid[1, 1], wspace=0, hspace=0,
        # )
        #
        # self.tl_ax_ctr, self.tl_ax_top, self.tl_ax_rgt = self.setupJointGrid(
        #     self.fig, gs_top_lft
        # )
        # self.tr_ax_ctr, self.tr_ax_top, self.tr_ax_rgt = self.setupJointGrid(
        #     self.fig, gs_top_rgt
        # )
        #
        # self.bl_ax_t = self.fig.add_subplot(gs_btm_lft[0])
        # self.bl_ax_b = self.fig.add_subplot(gs_btm_lft[1])
        # self.br_ax = self.fig.add_subplot(gs_btm_rgt[0])
        #
        # self.axes = (
        #     self.tl_ax_ctr,
        #     self.tl_ax_top,
        #     self.tl_ax_rgt,
        # self.tr_ax_ctr,
        # self.tr_ax_top,
        # self.tr_ax_rgt,
        # self.bl_ax_b,
        # self.bl_ax_t,
        # self.br_ax,
        # )
        # self.axes_marg = (
        #     self.tl_ax_top,
        #     self.tl_ax_rgt,
        # self.tr_ax_top,
        # self.tr_ax_rgt,
        # )
        """
        Sets up a 2D-histogram layout similar to a seaborn JointGrid,
        but manually through matplotlib for compatibility reasons.
        """
        space_between = 0  # 0.01
        left, right = 0.08, 0.7
        bottom, height = 0.08, 0.7
        bottom_h = left_h = left + right + space_between

        rect_center = left, bottom, right, height
        rect_hist_top = left, bottom_h, right, 0.2
        rect_hist_right = left_h, bottom, 0.2, height

        self.ax_ctr = self.fig.add_axes(rect_center)
        self.ax_top = self.fig.add_axes(rect_hist_top)
        self.ax_rgt = self.fig.add_axes(rect_hist_right)

        self.axes = self.ax_ctr, self.ax_top, self.ax_rgt
        self.axes_marg = self.ax_top, self.ax_rgt

    def setupTwoColorImageLayout(self):
        """
        3-view layout for dual cam microscope setup (green, red, green/red).
        """
        self.ax_grn = self.fig.add_subplot(131)  # Green
        self.ax_red = self.fig.add_subplot(132)  # Red
        self.ax_grn_red = self.fig.add_subplot(133)  # Blend

        self.axes_single = self.ax_grn, self.ax_red
        self.axes_all = self.ax_grn, self.ax_red, self.ax_grn_red

        self.adjust_margins(fig=self.fig,
                            left=0.05,
                            right=0.95,
                            hspace=0,
                            wspace=0.04)

    def setupTwoColorTraceLayout(self):
        """
        Setup for viewing traces with 2 colors.
        """
        gs = self.fig.add_gridspec(nrows=5,
                                   ncols=1,
                                   height_ratios=[2, 2, 2, 2, 1])

        self.ax_grn = self.fig.add_subplot(gs[0])  # Green
        self.ax_acc = self.ax_grn.twinx()  # Red
        self.ax_red = self.fig.add_subplot(gs[1])  # ALEX
        self.ax_fret = self.fig.add_subplot(gs[2])  # FRET
        self.ax_stoi = self.fig.add_subplot(
            gs[3])  # Stoichiometry (should be the bottom-most)
        self.ax_ml = self.fig.add_subplot(gs[4])  # ML predictions

        self.axes = (
            self.ax_grn,
            self.ax_acc,
            self.ax_red,
            self.ax_fret,
            self.ax_stoi,
            self.ax_ml,
        )
        self.axes_c = list(
            zip((self.ax_grn, self.ax_acc, self.ax_red),
                ("D", "A", "A-direct")))

        self.adjust_margins(fig=self.fig,
                            hspace=0,
                            left=0.06,
                            right=0.94,
                            top=0.96,
                            bottom=0.04)

        self.traceOutlineColor()

    def setupDynamicPlotLayout(self):
        """
        Setup for a single panel plot.
        """
        self.axes = (self.fig.add_subplot(111, aspect="equal"), )
        for ax in self.axes:
            ax.set_xticks(())
            ax.set_yticks(())

        self.adjust_margins(fig=self.fig, margin=0.02)

    def setupSinglePlotLayout(self):
        """
        Setup for a single panel plot.
        """
        self.ax = self.fig.add_subplot(111, aspect="equal")
        self.adjust_margins(fig=self.fig, margin=0.02)

    def setupDoubleAxesPlotLayout(self):
        """
        Setup for two plots on top of each other
        """
        self.ax_top = self.fig.add_subplot(211)
        self.ax_btm = self.fig.add_subplot(212)

        self.axes = self.ax_top, self.ax_btm

        self.adjust_margins(
            fig=self.fig,
            hspace=0.30,
            wspace=0,
            left=0.02,
            right=0.98,
            bottom=0.09,
            top=0.98,
        )

    def setupTripleAxesPlotLayout(self):
        """
        Horizontal layout for three plots at a time
        """
        self.ax_lft = self.fig.add_subplot(131)
        self.ax_ctr = self.fig.add_subplot(132)
        self.ax_rgt = self.fig.add_subplot(133)

        self.adjust_margins(
            fig=self.fig,
            hspace=0.30,
            wspace=0,
            left=0.02,
            right=0.98,
            bottom=0.09,
            top=0.98,
        )

    def traceOutlineColor(self):
        """
        Updates the box outline and ticks for the traces displayer.
        """
        for ax in self.axes:
            ax.tick_params(axis="x",
                           which="both",
                           bottom=False,
                           labelbottom=False)
            ax.yaxis.label.set_color(gvars.color_gui_text)

        if hasattr(self, "ax_ml"):
            self.ax_ml.tick_params(axis="x",
                                   which="both",
                                   bottom=True,
                                   labelbottom=True)
            self.ax_ml.set_xlabel(
                "Frames")  # Assuming this is the bottom trace
        else:
            if self.ax_setup != "bypass":
                self.ax_stoi.tick_params(axis="x",
                                         which="both",
                                         bottom=True,
                                         labelbottom=True)
                self.ax_stoi.set_xlabel(
                    "Frames")  # Assuming this is the bottom trace

    def get_window_title(
            self):  # overwrite class method for default image name
        return self.defaultImageName
Exemple #26
0
    print(dict_var)


demo_selection = tk.StringVar(demo)
selections = [' ', 'pp_messreihe', 'sol_gel_messreihe', 'c']
demo_selection.set(selections[0])

option_1 = tk.OptionMenu(top,
                         demo_selection,
                         *selections,
                         command=lambda _: read_data(demo_selection.get()))

option_1.grid(row=0, column=0)

fig = Figure(figsize=(50, 50))
grid = fig.add_gridspec(12, 18)

fig_ax1 = fig.add_subplot(grid[:12, :-8])
fig_ax1.set_title('Kontaktwiderstand')
#fig_ax1.set_xlim([0, 21])
#fig_ax1.set_ylim([0, 50])

fig_ax2 = fig.add_subplot(grid[1:6, 5:10])
fig_ax2.set_title('KW @ 20bar')

fig_ax3 = fig.add_subplot(grid[:3, 12:])
fig_ax3.set_title('volumetrischer Gesamt-Leitwert [S/cm]')

fig_ax4 = fig.add_subplot(grid[4:7, 12:])
fig_ax4.set_title('volumetrischer Durchgangs-Leitwert [S/cm]')
def visualize(data_pair,
              data_format,
              figure: Figure = None,
              show_img_stats=True,
              bins: Union[str, int] = 'auto',
              class_names=None):
    """visualize dataset entry to matplotlib

    Args:
        data_pair (tuple-like): pair of image, label
        data_format (dict): vortex dataset's data_format
        figure (Figure, optional): matplotlib figure for drawing. Defaults to None.
        show_img_stats (bool, optional): show boxplot and histograms. Defaults to True.
        bins (Union[str,int], optional): number of bins. Defaults to 'auto'.
        class_names (list, optional): vortex dataset's class_names. Defaults to None.

    Returns:
        dict: mapping from string to matplotlib axes
    """
    if not figure:
        his_fig, his_ax = plt.subplots()
        box_fig, box_ax = plt.subplots()
        img_fig, img_ax = plt.subplots()
    elif show_img_stats:
        gs = figure.add_gridspec(2, 4)
        his_fig, his_ax = figure, figure.add_subplot(gs[0, 2:])
        box_fig, box_ax = figure, figure.add_subplot(gs[1, 2:])
        img_fig, img_ax = figure, figure.add_subplot(gs[0:, 0:2])
    else:
        gs = figure.add_gridspec(1, 1)
        his_fig, his_ax = None, None
        box_fig, box_ax = None, None
        img_fig, img_ax = figure, figure.add_subplot(gs[0:, 0:2])

    image, labels = data_pair
    # since this visualization script read the dataset (instead of wrapper/dataloader)
    # there is a chance that PIL image is given
    if isinstance(image, PIL.Image.Image):
        image = np.array(image)
    h, w, c = image.shape

    # tensor across observation for histogram and boxplot
    tensor: np.ndarray = np.asarray(image).flatten()

    if his_ax:
        histogram = np.histogram(tensor, bins=bins)
        his_ax.hist(tensor, bins=bins)
    if box_ax:
        red_square = dict(markerfacecolor='r', marker='s')
        box_ax.boxplot(tensor, vert=False, flierprops=red_square)

    # dont plot here, let the caller decide
    # plt.show()

    # TODO: do not hard code here, read from standard module (if any) instead
    classification_format = ['class_label']
    detection_format = ['bounding_box', 'class_label']

    data_format_keys = list(data_format.keys())

    # TODO: matplotlib expect RGB, torchvisiondataset use RGB, vortex assume opencv (BGR)
    # image = cv2.cvtColor(image, cv2.BGR2RGB)

    if data_format_keys == classification_format:
        # TODO: use np.take to slice labels, add class_names if any
        bl = int(0), int(0.9 * h)
        class_label = labels[0] if isinstance(labels, list) else int(labels)
        color = vortex_visual.colors[class_label]
        # TODO: do not change global variable, pass as param instead
        # vortex_visual.font_scale = 0.25
        image = vortex_visual.draw_label(image,
                                         obj_class=class_label,
                                         confidence=1,
                                         bl=bl,
                                         color=color,
                                         class_names=class_names)
    elif data_format_keys == detection_format:
        # TODO: dont do this here, move to vortex_visual
        # TODO: use np.take to slice labels, add class_names if any
        bbox_fmt = data_format['bounding_box']
        clss_fmt = data_format['class_label']
        bounding_boxes = np.take(labels, bbox_fmt['indices'], bbox_fmt['axis'])
        class_labels = np.take(labels, clss_fmt['indices'], clss_fmt['axis'])
        confidences = [1] * len(class_labels)
        bounding_boxes[:, 0] *= w
        bounding_boxes[:, 1] *= h
        bounding_boxes[:, 2] *= w
        bounding_boxes[:, 3] *= h
        image = draw_bboxes(image,
                            bboxes=bounding_boxes.astype(int),
                            classes=class_labels,
                            confidences=confidences,
                            format='xywh',
                            class_names=class_names)

    img_ax.imshow(image)

    visualization = EasyDict(histogram=dict(
        figure=his_fig,
        axes=his_ax,
    ),
                             boxplot=dict(
                                 feature=box_fig,
                                 axes=box_ax,
                             ),
                             image=dict(
                                 figure=img_fig,
                                 axes=img_ax,
                             ))
    return visualization
Exemple #28
0
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib import style
import tkinter as tk
import numpy as np
import soundcard as sc
from scipy.io.wavfile import read

LARGE_FONT = ("Verdanna", 30)
style.use("ggplot")

f = Figure(figsize=(40, 15), dpi=100)
gs = f.add_gridspec(2, 5)

recordtime = 3

mic = sc.get_microphone('Shure')


def ReadWav(wavstrg):
    red = read(wavstrg)
    samps = []
    for k in red[1]:
        samps.append(k[1])
    samps = samps / np.max(samps)
    return samps

def multi_plot_2d_scatter_hist(
        varx: InVar | OutVar,
        vary: InVar | OutVar,
        cases: None | int | Iterable[int] = None,
        highlight_cases: None | int | Iterable[int] = empty_list(),
        rug_plot: bool = False,
        cov_plot: bool = True,
        cov_p: None | float | Iterable[float] = None,
        cumulative: bool = False,
        invar_space: InVarSpace | Iterable[InVarSpace] = InVarSpace.NUMS,
        fig: Figure = None,
        title: str = '',
        plotkwargs: dict = dict(),
) -> tuple[Figure, tuple[Axes, ...]]:
    """
    Plot two variables against each other with a central scatterplot and two
    histograms along the x and y axes.

    Parameters
    ----------
    varx : monaco.mc_var.InVar | monaco.mc_var.OutVar
        The x variable to plot.
    vary : monaco.mc_var.InVar | monaco.mc_var.OutVar
        The y variable to plot.
    cases : None | int | Iterable[int], default: None
        The cases to plot. If None, then all cases are plotted.
    highlight_cases : None | int | Iterable[int], default: []
        The cases to highlight. If [], then no cases are highlighted.
    rug_plot : bool, default: False
        Whether to plot rug marks.
    cov_plot : bool, default: False
        Whether to plot a covariance ellipse at a certain gaussian percentile
        level.
    cov_p : None | float | Iterable[float], default: None
        The gaussian percentiles for the covariance plot.
    cumulative : bool, default: False
        Whether to plot the histograms as cumulative distribution functions.
    invar_space : monaco.InVarSpace | Iterable[InVarSpace], default: 'nums'
        The space to plot invars in, either 'nums' or 'pcts'. If an iterable,
        specifies this individually for each of varx, vary, and varz.
    fig : matplotlib.figure.Figure, default: None
        The figure handle to plot in. If None, a new figure is created.
    title : str, default: ''
        The figure title.

    Returns
    -------
    (fig, (ax1, ax2, ax3)) : (matplotlib.figure.Figure,
    (matplotlib.axes.Axes, matplotlib.axes.Axes, matplotlib.axes.Axes))
        fig is the figure handle for the plot.
        (ax1, ax2, ax3) are the axes handles for the central, y-axis, and
        x-axis plots, respectively.
    """
    fig = handle_fig(fig)

    gs = fig.add_gridspec(4, 4)
    ax1 = fig.add_subplot(gs[3, 1:4])
    ax2 = fig.add_subplot(gs[0:3, 0])
    ax3 = fig.add_subplot(gs[0:3, 1:4], sharex=ax1, sharey=ax2)

    plot_hist(varx,
              cases=cases,
              highlight_cases=highlight_cases,
              cumulative=cumulative,
              rug_plot=False,
              invar_space=invar_space,
              ax=ax1,
              title='',
              plotkwargs=plotkwargs)
    plot_hist(vary,
              cases=cases,
              highlight_cases=highlight_cases,
              cumulative=cumulative,
              rug_plot=False,
              invar_space=invar_space,
              ax=ax2,
              title='',
              plotkwargs=plotkwargs,
              orientation=PlotOrientation.HORIZONTAL)
    plot_2d_scatter(varx,
                    vary,
                    cases=cases,
                    highlight_cases=highlight_cases,
                    rug_plot=rug_plot,
                    cov_plot=cov_plot,
                    cov_p=cov_p,
                    invar_space=invar_space,
                    ax=ax3,
                    title='',
                    plotkwargs=plotkwargs)

    ax1.set_ylabel('')
    ax2.set_xlabel('')
    ax3.set_xlabel('')
    ax3.set_ylabel('')
    ax3.xaxis.set_tick_params(labelbottom=False)
    ax3.yaxis.set_tick_params(labelbottom=False)

    plt.suptitle(title, y=.93)

    return fig, (ax1, ax2, ax3)