Esempio n. 1
0
class PlotFigure(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Test wxFigure")
        self.fig = p.figure(1)
        self.ax = p.subplot(111)
        self.canvas = FigureCanvasWxAgg(self, -1, self.fig)
        #        self.canvas = self.ax.figure.canvas
        self.background = None
        self.cnt = 0
        self.tstart = time.time()
        wx.EVT_TIMER(self, TIMER_ID, self.update_line)

    def init_plot(self):
        # create the initial line
        x = nx.arange(0, 2 * nx.pi, 0.01)
        self.l_pos_a = [((0, 0), (1, 1)), ((0, 1), (1, 0))]
        self.l_pos_b = [((0, 0), (0, 1)), ((1, 1), (1, 0))]
        self.line_c = LineCollection(self.l_pos_a, animated=True)
        line, = p.plot(x, nx.sin(x), animated=False)
        self.ax.add_collection(self.line_c)

    def update_line(self, evt):
        # save the clean slate background -- everything but the animated line
        # is drawn and saved in the pixel buffer background
        if self.background is None:
            self.background = self.canvas.copy_from_bbox(self.ax.bbox)

        # restore the clean slate background
        self.canvas.restore_region(self.background)
        # update the data
        #    line.set_ydata(nx.sin(x+update_line.cnt/10.0))
        if (self.cnt / 10) % 2 == 0:
            self.line_c.set_verts(self.l_pos_b)
        else:
            self.line_c.set_verts(self.l_pos_a)
        # just draw the animated artist
        self.ax.draw_artist(self.line_c)
        # just redraw the axes rectangle
        self.canvas.blit(self.ax.bbox)

        if self.cnt == 50:
            # print the timing info and quit
            print 'FPS:', self.cnt / (time.time() - self.tstart)
            sys.exit()

        self.cnt += 1

        #        wx.WakeUpIdle()
        return True
Esempio n. 2
0
    def set_data(self, zname=None, zdata=None, zcolor=None, plot_type="poly"):
        if zdata != None:
            if plot_type is "poly":
                if zname not in self.clts:  #plottables['plotted']:#self.pd.list_data():
                    clt = PolyCollection(
                        [], alpha=0.5, antialiased=True
                    )  #, rasterized=False, antialiased=False)
                    if zcolor is not None:
                        clt.set_color(colorConverter.to_rgba(zcolor))
                    self.clts[zname] = clt
                    self.axe.add_collection(self.clts[zname])
                self.clts[zname].set_verts(zdata)

            elif plot_type is "line":
                if zname not in self.clts:
                    clt = LineCollection(
                        zdata)  #, linewidths=(0.5, 1, 1.5, 2),
                    #linestyles='solid', colors=("red", "blue", "green"))
                    if zcolor is not None:
                        clt.set_color(zcolor)
                    else:
                        clt.set_array(arange(len(zdata)))
                else:
                    self.clts[zname].set_verts(zdata)
                    #self.set_xlim(x.min(), x.max())
                    #self.set_ylim(ys.min(), ys.max())

            elif plot_type is "scatter":
                self.axe.scatter(zdata, zdata)
            elif plot_type is "colormap":
                self.axe.pcolormesh(x, y, z)

        if 0:
            x = arange(3)
            ys = array([x + i for i in arange(5)])
            #xdata=arange(len(getattr(self, zname)))

            data = [list(zip(x, y)) for y in ys]
            line_segments = LineCollection(data,
                                           linewidths=1,
                                           linestyles='solid',
                                           colors=mycolors)
            print data
            print len(data)
            #print line_segments.properties()
            #print line_segments.set_hatch("O")
            #print dir(self.axe)

            print[p.vertices for p in line_segments.get_paths()]  #)
            print line_segments.get_segments()
            line_segments.set_array(arange(len(data)))

            x = arange(3)
            ys = array([x + i for i in arange(2)])
            #xdata=arange(len(getattr(self, zname)))

            data = [list(zip(x, y)) for y in ys]

            line_segments.set_verts(data)
            #self.axe.add_collection(line_segments, autolim=True)

            clt = self.axe.scatter(x, x)
            #clt.set_linestyle("solid")
            print dir(clt)
            print clt.get_paths()
        if 0:
            #clt=QuadMesh(0, 0, [1])

            n = 12
            x = linspace(-1.5, 1.5, n)
            y = linspace(-1.5, 1.5, n * 2)
            X, Y = meshgrid(x, y)
            print X
            Qx = cos(Y) - cos(X)
            Qz = sin(Y) + sin(X)
            Qx = (Qx + 1.1)
            Z = sqrt(X**2 + Y**2) / 5
            Z = (Z - Z.min()) / (Z.max() - Z.min())
            Zm = ma.masked_where(fabs(Qz) < 0.5 * amax(Qz), Z)

            #ax = fig.add_subplot(121)
            #self.axe.set_axis_bgcolor("#bdb76b")
            clt = self.axe.pcolormesh(Z)
            #print dir(clt)
            self.axe.set_title('Without masked values')
Esempio n. 3
0
class SpiroGraph(object):

    '''
    Spirograph drawer with matplotlib slider widgets to change parameters.
    Parameters of line are:

        R: The radius of the big circle
        r: The radius of the small circle which rolls along the inside of the
           bigger circle
        p: distance from centre of smaller circle to point in the circle where
           the pen hole is.
        tmax: the angle through which the smaller circle is rotated to draw the
              spirograph
        tstep: how often matplotlib plots a point
        a, b, c: parameters of the linewidth equation.
    '''

    # kwargs for each of the matplotlib sliders
    slider_kwargs = (
        {'label': 't_max', 'valmin': np.pi, 'valmax': 200 * np.pi,
         'valinit': tmax0, 'valfmt': PiString()},
        {'label': 't_step', 'valmin': 0.01,
         'valmax': 10, 'valinit': tstep0},
        {'label': 'R', 'valmin': 1, 'valmax': 200, 'valinit': R0},
        {'label': 'r', 'valmin': 1, 'valmax': 200, 'valinit': r0},
        {'label': 'p', 'valmin': 1, 'valmax': 200, 'valinit': p0},
        {'label': 'colour', 'valmin': 0, 'valmax': 1, 'valinit': 1},
        {'label': 'width_a', 'valmin': 0.5, 'valmax': 10, 'valinit': 1},
        {'label': 'width_b', 'valmin': 0, 'valmax': 10, 'valinit': 0},
        {'label': 'width_c', 'valmin': 0, 'valmax': 10, 'valinit': 0.5})

    rbutton_kwargs = (
        {'labels': ('black', 'white'), 'activecolor': 'white', 'active': 0},
        {'labels': ('solid', 'variable'), 'activecolor': 'white', 'active': 0})

    def __init__(self, colormap, figsize=(7, 10)):
        self.colormap_name = colormap
        self.variable_color = False
        # Use ScalarMappable to map full colormap to range 0 - 1
        self.colormap = ScalarMappable(cmap=colormap)
        self.colormap.set_clim(0, 1)

        # set up main axis onto which to draw spirograph
        self.figsize = figsize
        plt.rcParams['figure.figsize'] = figsize
        self.fig, self.mainax = plt.subplots()
        plt.subplots_adjust(bottom=0.3)
        title = self.mainax.set_title('Spirograph Drawer!',
                                      size=20,
                                      color='white')
        self.text = [title, ]
        # set up slider axes
        self.slider_axes = [plt.axes([0.25, x, 0.65, 0.015])
                            for x in np.arange(0.05, 0.275, 0.025)]
        # same again for radio buttons
        self.rbutton_axes = [plt.axes([0.025, x, 0.1, 0.15])
                             for x in np.arange(0.02, 0.302, 0.15)]
        # use log scale for tstep slider
        self.slider_axes[1].set_xscale('log')
        # turn off frame, ticks and tick labels for all axes
        for ax in chain(self.slider_axes, self.rbutton_axes, [self.mainax, ]):
            ax.axis('off')
        # use axes and kwargs to create list of sliders/rbuttons
        self.sliders = [Slider(ax, **kwargs)
                        for ax, kwargs in zip(self.slider_axes,
                                              self.slider_kwargs)]
        self.rbuttons = [RadioButtons(ax, **kwargs)
                         for ax, kwargs in zip(self.rbutton_axes,
                                               self.rbutton_kwargs)]
        self.update_figcolors()

        # set up initial line
        self.t = np.arange(0, tmax0, tstep0)
        x, y = spiro_linefunc(self.t, R0, r0, p0)
        self.linecollection = LineCollection(
            segments(x, y),
            linewidths=spiro_linewidths(self.t, a0, b0, c0),
            color=self.colormap.to_rgba(col0))
        self.mainax.add_collection(self.linecollection)

        # creates the plot and connects sliders to various update functions
        self.run()

    def update_figcolors(self, bgcolor='black'):
        '''
        function run by background color radiobutton. Sets all labels, text,
        and sliders to foreground color, all axes to background color
        '''
        fgcolor = 'white' if bgcolor == 'black' else 'black'
        self.fig.set_facecolor(bgcolor)
        self.mainax.set_axis_bgcolor(bgcolor)
        for ax in chain(self.slider_axes, self.rbutton_axes):
            ax.set_axis_bgcolor(bgcolor)

        # set fgcolor elements to black or white, mostly elements of sliders
        for item in chain(map(attrgetter('label'), self.sliders),
                          map(attrgetter('valtext'), self.sliders),
                          map(attrgetter('poly'), self.sliders),
                          self.text,
                          *map(attrgetter('labels'), self.rbuttons)):
            item.set_color(fgcolor)

        self.update_radiobutton_colors()
        plt.draw()

    def update_linewidths(self, *args):
        '''
        function run by a, b and c parameter sliders. Sets width of each line
        in linecollection according to sine function
        '''
        a, b, c = (s.val for s in self.sliders[6:])
        self.linecollection.set_linewidths(spiro_linewidths(self.t, a, b, c))
        plt.draw()

    def update_linecolors(self, *args):
        '''
        function run by color slider and indirectly by variable/solid color
        radiobutton. Updates colors of each line in linecollection using the
        set colormap.
        '''
        # get current color value (a value between 1 and 0)
        col_val = self.sliders[5].val
        if not self.variable_color:
            # if solid color, convert color value to rgb and set the color
            self.linecollection.set_color(self.colormap.to_rgba(col_val))
        else:
            # create values between 0 and 1 for each line segment
            colors = (self.t / max(self.t)) + col_val
            # use color value to roll colors
            colors[colors > 1] -= 1
            self.linecollection.set_color(
                [self.colormap.to_rgba(i) for i in colors])
        plt.draw()

    def update_lineverts(self, *args):
        '''
        function run by R, r, p, tmax and tstep sliders to update line vertices
        '''
        tmax, tstep, R, r, p = (s.val for s in self.sliders[:5])
        self.t = np.arange(0, tmax, tstep)
        x, y = spiro_linefunc(self.t, R, r, p)
        self.linecollection.set_verts(segments(x, y))
        # change axis limits to pad new line nicely
        self.mainax.set(xlim=(min(x) - 5, max(x) + 5),
                        ylim=(min(y) - 5, max(y) + 5))
        plt.draw()

    def update_linecolor_setting(self, val):
        '''
        function run by solid/variable colour slider, alters variable_color
        attribute then calls update_linecolors
        '''
        if val == 'variable':
            self.variable_color = True
        elif val == 'solid':
            self.variable_color = False
        # need to update radiobutton colors here.
        self.update_radiobutton_colors()
        self.update_linecolors()

    def update_radiobutton_colors(self):
        '''
        makes radiobutton colors correct even on a changing axis background
        '''
        bgcolor = self.rbuttons[0].value_selected
        fgcolor = 'white' if bgcolor == 'black' else 'black'
        for i, b in enumerate(self.rbuttons):
            # find out index of the active button
            active_idx = self.rbutton_kwargs[i]['labels'].index(
                b.value_selected)
            # set button colors accordingly
            b.circles[not active_idx].set_color(bgcolor)
            b.circles[active_idx].set_color(fgcolor)

    def run(self):
        '''
        set up slider functions
        '''
        verts_func = self.update_lineverts
        colors_func = self.update_linecolors
        widths_func = self.update_linewidths
        # create iterable of slider funcs to zip with sliders
        slider_update_funcs = chain(repeat(verts_func, 5),
                                    [colors_func, ],
                                    repeat(widths_func, 3))
        # set slider on_changed functions
        for s, f in zip(self.sliders, slider_update_funcs):
            s.on_changed(f)

        self.rbuttons[0].on_clicked(self.update_figcolors)
        self.rbuttons[1].on_clicked(self.update_linecolor_setting)
        plt.show()