Python matplotlib.widgets.Button() Examples

The following are 19 code examples of matplotlib.widgets.Button(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module matplotlib.widgets , or try the search function .
Example #1
Source Project: spotpy   Author: thouska   File: mpl.py    License: MIT License 6 votes vote down vote up
def __init__(self, rect, wtype, *args, **kwargs):
        """
        Creates a matplotlib.widgets widget
        :param rect: The rectangle of the position [left, bottom, width, height] in relative figure coordinates
        :param wtype: A type from matplotlib.widgets, eg. Button, Slider, TextBox, RadioButtons
        :param args: Positional arguments passed to the widget
        :param kwargs: Keyword arguments passed to the widget and events used for the widget
                       eg. if wtype is Slider, on_changed=f can be used as keyword argument

        """
        self.ax = plt.axes(rect)
        events = {}
        for k in list(kwargs.keys()):
            if k.startswith('on_'):
                events[k] = kwargs.pop(k)
        self.object = wtype(self.ax, *args, **kwargs)
        for k in events:
            if hasattr(self.object, k):
                getattr(self.object, k)(events[k]) 
Example #2
Source Project: visualqc   Author: raamana   File: interfaces.py    License: Apache License 2.0 6 votes vote down vote up
def add_navigation(self, user_next_callback=None,
                       user_quit_callback=None):
        """Navigation elements"""

        ax_bt_quit = self.fig.add_axes(cfg.position_quit_button,
                              facecolor=cfg.color_quit_axis, aspect='equal')
        ax_bt_next = self.fig.add_axes(cfg.position_next_button,
                              facecolor=cfg.color_quit_axis, aspect='equal')
        self.bt_quit = Button(ax_bt_quit, 'Quit', hovercolor='red')
        self.bt_next = Button(ax_bt_next, 'Next', hovercolor='xkcd:greenish')
        #
        self.bt_quit.label.set_color(cfg.color_navig_text)
        self.bt_next.label.set_color(cfg.color_navig_text)
        # new impl to take control of blocking behav of plt.show()
        if user_next_callback is not None and user_quit_callback is not None:
            self.bt_next.on_clicked(user_next_callback)
            self.bt_quit.on_clicked(user_quit_callback)
        else:
            # previous impl - gives no control over blocking plt.show()
            self.bt_quit.on_clicked(self.builtin_quit)
            self.bt_next.on_clicked(self.builtin_next) 
Example #3
Source Project: transparent_latent_gan   Author: SummitKwan   File: script_generation_interactive.py    License: MIT License 6 votes vote down vote up
def create_button(idx_feature):
    """ function to built button groups for one feature """
    x, y, w, h = get_loc_control(idx_feature)

    plt.text(x+w/2, y+h/2+0.01, feature_name[idx_feature], horizontalalignment='center',
             transform=plt.gcf().transFigure)

    ax_neg = plt.axes((x + w / 8, y, w / 4, h / 2))
    b_neg = widgets.Button(ax_neg, '-', hovercolor='0.1')
    b_neg.on_clicked(lambda event:
                     callback.modify_along_feature(event, idx_feature, step_size=-1 * step_size))

    ax_pos = plt.axes((x + w *5/8, y, w / 4, h / 2))
    b_pos = widgets.Button(ax_pos, '+', hovercolor='0.1')
    b_pos.on_clicked(lambda event:
                     callback.modify_along_feature(event, idx_feature, step_size=+1 * step_size))

    ax_lock = plt.axes((x + w * 3/8, y, w / 4, h / 2))
    b_lock = widgets.CheckButtons(ax_lock, ['L'], [False])
    b_lock.on_clicked(lambda event:
                      callback.set_feature_lock(event, idx_feature))
    return b_neg, b_pos, b_lock 
Example #4
Source Project: animatplot   Author: t-makaro   File: animation.py    License: MIT License 6 votes vote down vote up
def toggle(self, ax=None):
        """Creates a play/pause button to start/stop the animation

        Parameters
        ----------
        ax : matplotlib.axes.Axes, optional
            The matplotlib axes to attach the button to.
        """
        if ax is None:
            adjust_plot = {'bottom': .2}
            rect = [.78, .03, .1, .07]

            plt.subplots_adjust(**adjust_plot)
            self.button_ax = plt.axes(rect)
        else:
            self.button_ax = ax

        self.button = Button(self.button_ax, "Pause")
        self.button.label2 = self.button_ax.text(
            0.5, 0.5, 'Play',
            verticalalignment='center',
            horizontalalignment='center',
            transform=self.button_ax.transAxes
        )
        self.button.label2.set_visible(False)

        def pause(event):
            if self._pause:
                self.animation.event_source.start()
                self.button.label.set_visible(True)
                self.button.label2.set_visible(False)
            else:
                self.animation.event_source.stop()
                self.button.label.set_visible(False)
                self.button.label2.set_visible(True)
            self.fig.canvas.draw()
            self._pause ^= True
        self.button.on_clicked(pause) 
Example #5
Source Project: resonator_tools   Author: sebastianprobst   File: circuit.py    License: GNU General Public License v2.0 6 votes vote down vote up
def __init__(self,porttype):
		self.porttype = porttype
		self.results = []
	
#def GUIfit(porttype,f_data,z_data_raw):
#	'''
#	GUI based fitting process enabeling cutting the data and manually setting the delay
#	It employs the Matplotlib widgets
#	return f1, f2 and delay, which should be employed for the real fitting
#	'''
#	if porttype=='direct':
#		p = reflection_port(f_data=f_data,z_data_raw=z_data_raw)
#	elif porttype =='notch':
#		p = notch_port(f_data=f_data,z_data_raw=z_data_raw)
#	else:
#		warnings.warn('Not supported!')
#		return None
#	import matplotlib.pyplot as plt
#	from matplotlib.widgets import Slider, Button, RadioButtons
#	#plt.style.use('ggplot')
#	fig, axes = plt.subplots(nrows=2,ncols=2)
#	
#	return f1,f2,delay 
Example #6
Source Project: roipoly.py   Author: jdoepfert   File: roipoly.py    License: Apache License 2.0 5 votes vote down vote up
def make_buttons(self):
        ax_add_btn = plt.axes([0.7, 0.02, 0.1, 0.04])
        ax_finish_btn = plt.axes([0.81, 0.02, 0.1, 0.04])
        btn_finish = Button(ax_finish_btn, 'Finish')
        btn_finish.on_clicked(self.finish)
        btn_add = Button(ax_add_btn, 'New ROI')
        btn_add.on_clicked(self.add)
        plt.show(block=True) 
Example #7
Source Project: crappy   Author: LaboratoireMecaniqueLille   File: grapher.py    License: GNU General Public License v2.0 5 votes vote down vote up
def prepare(self):
    if self.backend:
      plt.switch_backend(self.backend)
    self.f = plt.figure(figsize=self.window_size)
    self.ax = self.f.add_subplot(111)
    self.lines = []
    for _ in self.labels:
      if self.interp:
        self.lines.append(self.ax.plot([], [])[0])
      else:
        self.lines.append(self.ax.step([], [])[0])
    # Keep only 1/factor points on each line
    self.factor = [1 for i in self.labels]
    # Count to drop exactly 1/factor points, no more and no less
    self.counter = [0 for i in self.labels]
    legend = [y for x, y in self.labels]
    plt.legend(legend, bbox_to_anchor=(-0.03, 1.02, 1.06, .102), loc=3,
               ncol=len(legend), mode="expand", borderaxespad=1)
    plt.xlabel(self.labels[0][0])
    plt.ylabel(self.labels[0][1])
    plt.grid()
    self.axclear = plt.axes([.8,.02,.15,.05])
    self.bclear = Button(self.axclear,'Clear')
    self.bclear.on_clicked(self.clear)

    if self.window_pos:
      mng = plt.get_current_fig_manager()
      mng.window.wm_geometry("+%s+%s" % self.window_pos)
    plt.draw()
    plt.pause(.001) 
Example #8
Source Project: visual_dynamics   Author: alexlee-gk   File: action_panel.py    License: MIT License 5 votes vote down vote up
def _initialize_buttons(self):
        self._buttons = {}
        for key, action in self._actions.items():
            if action.axis_pos is None:
                continue
            
            button_name = '%s\n(%s)' % (action.name, action.kb)
            if ROS_ENABLED and action.pb:
                ps3_buttons = [config['inverted_ps3_button'][i] for i in action.pb]
                button_name += '\n(%s)' % ',\n'.join(ps3_buttons)

            self._buttons[key] = Button(self._axarr[action.axis_pos], button_name)
            self._buttons[key].on_clicked(action.func) 
Example #9
Source Project: spotpy   Author: thouska   File: mpl.py    License: MIT License 5 votes vote down vote up
def __init__(self, setup):
        """
        Creates the GUI

        :param setup: A spotpy setup
        """
        self.fig = plt.figure(type(setup).__name__)
        self.ax = plt.axes([0.05, 0.1, 0.65, 0.85])
        self.button_run = Widget([0.75, 0.01, 0.1, 0.03], Button, 'Simulate', on_clicked=self.run)
        self.button_clear = Widget([0.87, 0.01, 0.1, 0.03], Button, 'Clear plot', on_clicked=self.clear)
        self.parameter_values = {}
        self.setup = setup
        self.sliders = self._make_widgets()
        self.lines = []
        self.clear() 
Example #10
Source Project: aggregation   Author: zooniverse   File: marmot.py    License: Apache License 2.0 5 votes vote down vote up
def __run__(self):
        # create the welcome window
        run_type = None
        t = tkinter.Toplevel(self.root)
        t.resizable(False,False)
        frame = ttk.Frame(t, padding="3 3 12 12")
        frame.grid(column=0, row=0, sticky=(tkinter.N, tkinter.W, tkinter.E, tkinter.S))
        frame.columnconfigure(0, weight=1)
        frame.rowconfigure(0, weight=1)
        ttk.Label(frame,text="Welcome to Marmot.").grid(column=1,row=1)
        def setup(require_gold_standard):
            # this will determine the whole run mode from here on in
            self.require_gold_standard = require_gold_standard
            self.subjects = self.__image_select__(require_gold_standard)
            # if r == "a":
            #     self.subjects = self.project.__get_retired_subjects__(1,True)
            #     self.run_mode = "a"
            # else:
            #     # when we want to explore subjects which don't have gold standard
            #     # basically creating some as we go
            #     # False => read in all subjects, not just those with gold standard annotations
            #     # todo - takes a while in read in all subjects. Better way?
            #     self.subjects = self.project.__get_retired_subjects__(1,False)
            #     self.run_mode = "b"
            random.shuffle(self.subjects)

            self.__thumbnail_display__()
            self.__add_buttons__()

            t.destroy()

        ttk.Button(frame, text="Explore results using existing expert annotations", command = lambda : setup(True)).grid(column=1, row=2)
        ttk.Button(frame, text="Explore and create gold standard on the fly", command = lambda : setup(False)).grid(column=1, row=3)

        t.lift(self.root)

        # self.outputButtons()
        self.root.mainloop() 
Example #11
Source Project: aggregation   Author: zooniverse   File: marmot.py    License: Apache License 2.0 5 votes vote down vote up
def __thumbnail_display__(self):
        # destroy any previously existing thumbnails - for when we're flipping through pages
        for thumb_index in range(len(self.thumbnails)-1,-1,-1):
            old_thumb = self.thumbnails.pop(thumb_index)
            old_thumb.destroy()

        for ii,subject_id in enumerate(self.subjects[9*self.page_index:9+9*self.page_index]):
            # do we already have a thumb for this file?
            thumb_path = DIR_THUMBS+str(subject_id)+".jpg"
            if not os.path.exists(thumb_path):
                self.__create_thumb__(subject_id)

            render_image = ImageTk.PhotoImage(file=thumb_path)

            but = ttk.Button(self.root, image=render_image)
            but.grid(column=ii/3+1, row=(1+ii)%3,sticky=tkinter.W)

            # the interaction with the subject will depend on whether we have gold standard data for it or not
            # if not, the user will need to create some
            if self.require_gold_standard:
                assert False
                # but.bind('<Button-1>', lambda event,t=thumb_path: self.(t) if self.run_mode == "a" else self.__create_gold_standard__(t))
            else:
                but.bind('<Button-1>', lambda event,t=thumb_path: self.__create_gold_standard__(t))

            self.thumbnails.append(but)

            # sigh - I hate having to do this
            # MUST keep - otherwise garbage collection in Python will remove it
            self.links.append(render_image)

        # todo - this window is not actually popping up
        # determine which of the subjects we are interested in have actually been processed
        # we may need to do some additional aggregation
        aggregated_subjects = self.project.__get_aggregated_subjects__(-1)

        not_aggregated = [s for s in self.subjects[:self.step_size] if s not in aggregated_subjects]

        # print not_aggregated
        if not_aggregated != []:
            self.project.__aggregate__([-1],self.subjects[:self.step_size]) 
Example #12
Source Project: aggregation   Author: zooniverse   File: marmot.py    License: Apache License 2.0 5 votes vote down vote up
def __add_buttons__(self):
        # for ii,thumbfile in enumerate(thumbfiles[:3]):

        ttk.Button(self.root, text="<--", command=self.__decrement__).grid(column=2, row=4)
        ttk.Button(self.root, text="-->", command=self.__increment__).grid(column=2, row=5)
        # ttk.Button(self.root, text="Threshold Plot", command=self.__calculate__).grid(column=1, row=5)
        # ttk.Button(self.root, text="Re-aggregate", command=self.__reaggregate__).grid(column=1, row=6)
        ttk.Button(self.root, text="ROC estimate", command=self.__roc_estimate__).grid(column=1, row=6) 
Example #13
Source Project: DeepLabCut   Author: DeepLabCut   File: skeleton.py    License: GNU Lesser General Public License v3.0 5 votes vote down vote up
def show(self):
        self.fig = plt.figure()
        ax = self.fig.add_subplot(111)
        ax.axis("off")
        lo = np.nanmin(self.xy, axis=0)
        hi = np.nanmax(self.xy, axis=0)
        center = (hi + lo) / 2
        w, h = hi - lo
        ampl = 1.3
        w *= ampl
        h *= ampl
        ax.set_xlim(center[0] - w / 2, center[0] + w / 2)
        ax.set_ylim(center[1] - h / 2, center[1] + h / 2)
        ax.imshow(self.image)
        ax.scatter(*self.xy.T, s=self.cfg["dotsize"] ** 2)
        ax.add_collection(self.lines)
        ax.invert_yaxis()

        self.lasso = LassoSelector(ax, onselect=self.on_select)
        ax_clear = self.fig.add_axes([0.85, 0.55, 0.1, 0.1])
        ax_export = self.fig.add_axes([0.85, 0.45, 0.1, 0.1])
        self.clear_button = Button(ax_clear, "Clear")
        self.clear_button.on_clicked(self.clear)
        self.export_button = Button(ax_export, "Export")
        self.export_button.on_clicked(self.export)
        self.fig.canvas.mpl_connect("pick_event", self.on_pick)
        plt.show() 
Example #14
Source Project: pyrealtime   Author: ewhitmire   File: circle_plot.py    License: MIT License 5 votes vote down vote up
def draw_empty_plot(self, ax):
        h, = ax.plot([], [], '.', markersize=50)
        self.button = Button(plt.axes([0.7, 0.01, 0.1, 0.05]), 'Zero')
        self.button.on_clicked(self.clicked)
        return h, 
Example #15
Source Project: pyrealtime   Author: ewhitmire   File: base.py    License: MIT License 5 votes vote down vote up
def draw_empty_plot(self, ax):
        ax_pause = plt.axes([0.81, 0.005, 0.1, 0.075])
        self.pause_button = Button(ax_pause, 'Pause')
        self.pause_button.on_clicked(self.pause)
        return [] 
Example #16
Source Project: TGC-Designer-Tools   Author: chadrockey   File: offset_ui_tool.py    License: Apache License 2.0 4 votes vote down vote up
def getManualRegistrationError(visual, heightmap, image_scale, pc):
    upper_left_enu = pc.ulENU()
    lower_right_enu = pc.lrENU()
    upper_left_latlon = pc.enuToLatLon(*upper_left_enu)
    lower_right_latlon = pc.enuToLatLon(*lower_right_enu)
    # Order is South, West, North, East
    result = OSMTGC.getOSMData(lower_right_latlon[0], upper_left_latlon[1], upper_left_latlon[0], lower_right_latlon[1])

    # TODO Scale, Sharpen, and Increase Local Constrast for these images to get potentially easier results?
    image_dict = {}
    image_dict["Visible"] = visual
    image_dict["Visible Golf"] = None
    image_dict["Heightmap"] = heightmap
    image_dict["Heightmap Golf"] = None

    fig, ax = plt.subplots()
    plt.title('Move Slider and Press Apply.  Close Window When Happy With Alignment')

    axcolor = 'green'
    plt.subplots_adjust(left=0.3, bottom=0.25)

    axx = plt.axes([0.25, 0.15, 0.65, 0.03], facecolor=axcolor)
    axy = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor=axcolor)
    sx = Slider(axx, 'West/East', -10.0, 10.0, valinit=0.0)
    sy = Slider(axy, 'South/North', -10.0, 10.0, valinit=0.0)

    applyax = plt.axes([0.8, 0.025, 0.1, 0.04])
    button = Button(applyax, 'Apply', color=axcolor, hovercolor='0.975')

    rax = plt.axes([0.05, 0.7, 0.15, 0.15], facecolor=axcolor)
    radio = RadioButtons(rax, image_dict.keys())
    update_image = partial(drawNewImage, ax, image_dict)
    radio.on_clicked(update_image)

    new_offset = partial(drawNewLocation, ax, image_dict, result, image_scale, radio, sx, sy, 1)
    button.on_clicked(new_offset)

    drawNewLocation(ax, image_dict, result, image_scale, radio, None, None, None, None)

    plt.show()

    return (sx.val, sy.val) 
Example #17
Source Project: CT-GAN   Author: ymirsky   File: GUI.py    License: MIT License 4 votes vote down vote up
def __init__(self, load_path, save_path=None):
        # init manipulator
        self.savepath = save_path
        self.filepaths = self._load_paths(load_path)  # load all scans filepaths in path
        self.fileindex = 0
        self.manipulator = scan_manipulator()
        self.manipulator.load_target_scan(self.filepaths[self.fileindex])
        self.hist_state = True
        self.inject_coords = []
        self.remove_coords = []

        # init plot
        self.eq = histEq(self.manipulator.scan)
        self.slices, self.cols, self.rows = self.manipulator.scan.shape
        self.ind = self.slices // 2
        self.pause_start = 0
        self.fig, self.ax = plt.subplots(1, 1, dpi=100)
        self.fig.suptitle('CT-GAN: Malicious Tampering of 3D Medical Imagery using Deep Learning\nTool by Yisroel Mirsky', fontsize=14, fontweight='bold')
        plt.subplots_adjust(bottom=0.2)
        self.ani_direction = 'down'
        self.animation = None
        self.animation_state = True
        self.plot()
        self.ax.set_title(os.path.split(self.filepaths[self.fileindex])[-1]) #filename


        # register click/scroll events
        self.action_state = 'inject' #default state
        self.fig.canvas.mpl_connect('button_press_event', self.onclick)
        self.fig.canvas.mpl_connect('scroll_event', self.onscroll)

        # register buttons
        axanim = plt.axes([0.1, 0.21, 0.2, 0.075])
        self.banim = Button(axanim, 'Toggle Animation')
        self.banim.on_clicked(self.toggle_animation)

        axinj = plt.axes([0.1, 0.05, 0.1, 0.075])
        axrem = plt.axes([0.21, 0.05, 0.1, 0.075])
        self.binj = Button(axinj, 'Inject')
        self.binj.on_clicked(self.inj_on)
        self.brem = Button(axrem, 'Remove')
        self.brem.on_clicked(self.rem_on)

        axhist = plt.axes([0.35, 0.05, 0.2, 0.075])
        self.bhist = Button(axhist, 'Toggle HistEQ')
        self.bhist.on_clicked(self.hist)

        axprev = plt.axes([0.59, 0.05, 0.1, 0.075])
        axsave = plt.axes([0.7, 0.05, 0.1, 0.075])
        axnext = plt.axes([0.81, 0.05, 0.1, 0.075])
        self.bnext = Button(axnext, 'Next')
        self.bnext.on_clicked(self.next)
        self.bprev = Button(axprev, 'Previous')
        self.bprev.on_clicked(self.prev)
        self.bsave = Button(axsave, 'Save')
        self.bsave.on_clicked(self.save)
        self.maximize_window()
        self.update()
        plt.show() 
Example #18
Source Project: DeepLabCut   Author: DeepLabCut   File: auxfun_videos.py    License: GNU Lesser General Public License v3.0 4 votes vote down vote up
def draw_bbox(video):
    import matplotlib.pyplot as plt
    from matplotlib.widgets import RectangleSelector, Button

    clip = cv2.VideoCapture(video)
    if not clip.isOpened():
        print("Video could not be opened. Skipping...")
        return

    success = False
    # Read the video until a frame is successfully read
    while not success:
        success, frame = clip.read()

    bbox = [0, 0, frame.shape[1], frame.shape[0]]

    def line_select_callback(eclick, erelease):
        bbox[:2] = int(eclick.xdata), int(eclick.ydata)  # x1, y1
        bbox[2:] = int(erelease.xdata), int(erelease.ydata)  # x2, y2

    def validate_crop(*args):
        fig.canvas.stop_event_loop()

    def display_help(*args):
        print(
            "1. Use left click to select the region of interest. A red box will be drawn around the selected region. \n\n2. Use the corner points to expand the box and center to move the box around the image. \n\n3. Click "
        )

    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.imshow(frame[:, :, ::-1])
    ax_help = fig.add_axes([0.9, 0.2, 0.1, 0.1])
    ax_save = fig.add_axes([0.9, 0.1, 0.1, 0.1])
    crop_button = Button(ax_save, "Crop")
    crop_button.on_clicked(validate_crop)
    help_button = Button(ax_help, "Help")
    help_button.on_clicked(display_help)

    rs = RectangleSelector(
        ax,
        line_select_callback,
        drawtype="box",
        minspanx=5,
        minspany=5,
        interactive=True,
        spancoords="pixels",
        rectprops=dict(facecolor="red", edgecolor="black", alpha=0.3, fill=True),
    )
    plt.show()

    # import platform
    # if platform.system() == "Darwin":  # for OSX use WXAgg
    #    fig.canvas.start_event_loop(timeout=-1)
    # else:
    fig.canvas.start_event_loop(timeout=-1)  # just tested on Ubuntu I also need this.
    #    #fig.canvas.stop_event_loop()

    plt.close(fig)
    return bbox 
Example #19
Source Project: rl-testbed-for-energyplus   Author: IBM   File: energyplus_model.py    License: MIT License 4 votes vote down vote up
def show_progress(self):
        self.monitor_file = self.log_dir + '/monitor.csv'

        # Read progress file
        if not self.read_monitor_file():
            print('Progress data is missing')
            sys.exit(1)

        # Initialize graph
        plt.rcdefaults()
        plt.rcParams['font.size'] = 6
        plt.rcParams['lines.linewidth'] = 1.0
        plt.rcParams['legend.loc'] = 'lower right'

        self.fig = plt.figure(1, figsize=(16, 10))

        # Show widgets
        axcolor = 'lightgoldenrodyellow'
        self.axprogress = self.fig.add_axes([0.15, 0.10, 0.70, 0.15], facecolor=axcolor)
        self.axslider = self.fig.add_axes([0.15, 0.04, 0.70, 0.02], facecolor=axcolor)
        axfirst = self.fig.add_axes([0.15, 0.01, 0.03, 0.02])
        axlast = self.fig.add_axes([0.82, 0.01, 0.03, 0.02])
        axprev = self.fig.add_axes([0.46, 0.01, 0.03, 0.02])
        axnext = self.fig.add_axes([0.51, 0.01, 0.03, 0.02])

        # Slider is drawn in plot_progress()

        # First/Last button
        self.button_first = Button(axfirst, 'First', color=axcolor, hovercolor='0.975')
        self.button_first.on_clicked(self.first_episode_num)
        self.button_last = Button(axlast, 'Last', color=axcolor, hovercolor='0.975')
        self.button_last.on_clicked(self.last_episode_num)

        # Next/Prev button
        self.button_prev = Button(axprev, 'Prev', color=axcolor, hovercolor='0.975')
        self.button_prev.on_clicked(self.prev_episode_num)
        self.button_next = Button(axnext, 'Next', color=axcolor, hovercolor='0.975')
        self.button_next.on_clicked(self.next_episode_num)

        # Timer
        self.timer = self.fig.canvas.new_timer(interval=1000)
        self.timer.add_callback(self.check_update)
        self.timer.start()

        # Progress data
        self.axprogress.set_xmargin(0)
        self.axprogress.set_xlabel('Episodes')
        self.axprogress.set_ylabel('Reward')
        self.axprogress.grid(True)
        self.plot_progress()

        # Plot latest episode
        self.update_episode(self.num_episodes - 1)

        plt.show()