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
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')
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()