def __init__(self,epsilon=10): """Initialize circle in given axss.""" axes = plt.gca() circ = CirclePolygon((0,0), 1., resolution=200) circ.set_fill(False) circ.set_edgecolor('b') axes.add_patch(circ) canvas = circ.figure.canvas canvas.mpl_connect('button_press_event', self.button_press_callback) canvas.mpl_connect('button_release_event', self.button_release_callback) canvas.mpl_connect('motion_notify_event', self.motion_notify_callback) self.epsilon = epsilon self.circ = circ self.arrow = None # Created by set_angle self.canvas = circ.figure.canvas self.external_hook = None self.axes = axes self.nr_pts = 0 self.arrow_colour = {'default': 'r', 'selected': 'g'} self.arrow_mode = 'default' self.set_angle(np.pi / 4.)
def plot_point(self, x, y, r): log.debug('x=%f, y=%f %s'%(x,y, r)) circ = CirclePolygon((x,y), 5, alpha=0.75) if r == 'r': col = self.cmap[len(self.pointr)%20] circ.set_color(col) self.ax1.add_patch(circ) self.pointr.append((x, y)) else: col = self.cmap[len(self.pointl)%20] circ.set_color(col) self.ax2.add_patch(circ) self.pointl.append((x, y)) if isinstance(self.F, np.ndarray): self.draw_line(x, y, r, col) self.fig.canvas.draw()
def plotCov(cov, refl, point, map, grid_spacing, file_name, roi=50, normalize=(-1, 1)): pylab.figure(figsize=(10, 8)) pt_z, pt_lat, pt_lon = point pt_x, pt_y = map(pt_lon, pt_lat) dx, dy = grid_spacing nx, ny = cov.shape xs, ys = np.meshgrid(dx * np.arange(nx), dy * np.arange(ny)) lbound, ubound = normalize dbound = (ubound - lbound) / 20. levels = np.arange(lbound, ubound + dbound, dbound) map.contourf(xs, ys, cov, levels=levels) pylab.colorbar() pylab.contour(xs, ys, refl, levels=[20., 40.], colors='k') pylab.plot(pt_x, pt_y, 'ko') roi_circle = CirclePolygon((pt_x, pt_y), roi * 1000., resolution=40, ec='k', fc='none') axes_box = Rectangle((0, 0), 1, 1, ec='w', fc='w', alpha=0.5, clip_path=roi_circle, transform=(pylab.gca().transAxes + pylab.gca().transData.inverted())) path_codes = [ Path.MOVETO ] + (axes_box.get_verts().shape[0] - 1) * [ Path.LINETO ] + [ Path.MOVETO ] + (roi_circle.get_verts().shape[0] - 1) * [ Path.LINETO ] path_verts = np.concatenate((axes_box.get_verts(), roi_circle.get_verts()[::-1])) mask_path = Path(path_verts, path_codes) mask_patch = PathPatch(mask_path, fc='w', ec='w', alpha=0.7) pylab.gca().add_patch(mask_patch) map.drawcoastlines(linewidth=1.5) map.drawcountries(linewidth=1.5) map.drawstates(linewidth=1.0) if not hasattr(map, 'counties'): map.readshapefile('countyp020', 'counties', linewidth=0.5) else: for county, data in izip(map.counties_info, map.counties): if county['STATE'] in ['NE', 'WY', 'CO']: pylab.gca().add_patch(Polygon(data, ec='k', fc='none', linewidth=0.5)) pylab.savefig(file_name) pylab.close() return
def _make_barbs(self, u, v, nflags, nbarbs, half_barb, empty_flag, length, pivot, sizes, fill_empty, flip): """Monkey-patch _make_barbs. Allows pivot to be a float value.""" # These control the spacing and size of barb elements relative to the # length of the shaft spacing = length * sizes.get('spacing', 0.125) full_height = length * sizes.get('height', 0.4) full_width = length * sizes.get('width', 0.25) empty_rad = length * sizes.get('emptybarb', 0.15) # Controls y point where to pivot the barb. pivot_points = dict(tip=0.0, middle=-length / 2.) # noqa: C408 # Check for flip if flip: full_height = -full_height endx = 0.0 try: endy = float(pivot) except ValueError: endy = pivot_points[pivot.lower()] # Get the appropriate angle for the vector components. The offset is # due to the way the barb is initially drawn, going down the y-axis. # This makes sense in a meteorological mode of thinking since there 0 # degrees corresponds to north (the y-axis traditionally) angles = -(ma.arctan2(v, u) + np.pi / 2) # Used for low magnitude. We just get the vertices, so if we make it # out here, it can be reused. The center set here should put the # center of the circle at the location(offset), rather than at the # same point as the barb pivot; this seems more sensible. circ = CirclePolygon((0, 0), radius=empty_rad).get_verts() if fill_empty: empty_barb = circ else: # If we don't want the empty one filled, we make a degenerate # polygon that wraps back over itself empty_barb = np.concatenate((circ, circ[::-1])) barb_list = [] for index, angle in np.ndenumerate(angles): # If the vector magnitude is too weak to draw anything, plot an # empty circle instead if empty_flag[index]: # We can skip the transform since the circle has no preferred # orientation barb_list.append(empty_barb) continue poly_verts = [(endx, endy)] offset = length # Add vertices for each flag for _ in range(nflags[index]): # The spacing that works for the barbs is a little to much for # the flags, but this only occurs when we have more than 1 # flag. if offset != length: offset += spacing / 2. poly_verts.extend( [[endx, endy + offset], [endx + full_height, endy - full_width / 2 + offset], [endx, endy - full_width + offset]]) offset -= full_width + spacing # Add vertices for each barb. These really are lines, but works # great adding 3 vertices that basically pull the polygon out and # back down the line for _ in range(nbarbs[index]): poly_verts.extend([(endx, endy + offset), (endx + full_height, endy + offset + full_width / 2), (endx, endy + offset)]) offset -= spacing # Add the vertices for half a barb, if needed if half_barb[index]: # If the half barb is the first on the staff, traditionally it # is offset from the end to make it easy to distinguish from a # barb with a full one if offset == length: poly_verts.append((endx, endy + offset)) offset -= 1.5 * spacing poly_verts.extend([(endx, endy + offset), (endx + full_height / 2, endy + offset + full_width / 4), (endx, endy + offset)]) # Rotate the barb according the angle. Making the barb first and # then rotating it made the math for drawing the barb really easy. # Also, the transform framework makes doing the rotation simple. poly_verts = transforms.Affine2D().rotate(-angle).transform( poly_verts) barb_list.append(poly_verts) return barb_list
def plot_skymap(self): fig = plt.figure(figsize=(12, 8)) ax = fig.add_subplot(111, projection="mollweide") # we define some custom colors to use transp_black = clrs.ColorConverter().to_rgba('black', alpha=0.6) transp_green = clrs.ColorConverter().to_rgba('green', alpha=0.4) transp_grey = clrs.ColorConverter().to_rgba('grey', alpha=0.5) # get probability associated with each sampled point prob = self._get_probability_array(pix=64) cm = plt.cm.get_cmap('viridis') sampling_points = ax.scatter(self._ra_samples, self._dec_samples, c=prob, cmap=cm, s=0.4, alpha=.75, zorder=1, label='Posterior sampling') fitted_position = ax.scatter(self._fit_coord[0], self._fit_coord[1], label='Fitted position', s=30,\ marker='+', color='black', zorder=3) if self._real_coord != None: real_position = ax.plot(self._real_coord[0], self._real_coord[1], linestyle='None', label='Real position', marker='*', markersize=10, markerfacecolor='yellow', markeredgecolor='black', markeredgewidth=0.1, zorder=3) sun_coord = self._get_sun_position() sun_position = ax.plot(sun_coord[0], sun_coord[1], linestyle='None', label='Sun position',\ marker='*', markersize=7, markerfacecolor='red', markeredgecolor='black', markeredgewidth=0.1, zorder=3) det_circles = [] for name in self._det_list: det_center = self._detectors.detectors[name].get_center( ).transform_to('icrs') ra_circ = np.radians(-det_center.ra.value + 180.) dec_circ = np.radians(det_center.dec.value) # fix overlapping between n5/b0 nb/b1 labels text_pos = 'center' if 'n5' in self._det_list and 'b0' in self._det_list and name == 'n5': text_pos = 'bottom' if 'n5' in self._det_list and 'b0' in self._det_list and name == 'b0': text_pos = 'top' if 'nb' in self._det_list and 'b1' in self._det_list and name == 'nb': text_pos = 'bottom' if 'nb' in self._det_list and 'b1' in self._det_list and name == 'b1': text_pos = 'top' circ = CirclePolygon((ra_circ, dec_circ), np.radians(15), resolution=100, antialiased=True) ax.annotate(name, xy=(ra_circ, dec_circ), ha='center', va=text_pos, fontsize=10) det_circles.append(circ) det_coll = PatchCollection(det_circles, edgecolor=transp_black, linewidth=1.5, color=transp_green, zorder=1) ax.add_collection(det_coll) # ellisses axes a_50 = self._cl_50[0][1] - self._cl_50[0][0] b_50 = self._cl_50[1][1] - self._cl_50[1][0] a_90 = self._cl_90[0][1] - self._cl_90[0][0] b_90 = self._cl_90[1][1] - self._cl_90[1][0] t = np.linspace(0, 2 * np.pi, 1000) ax.plot(self._fit_coord[0] + (a_50 / 2) * np.cos(t), self._fit_coord[1] + (b_50 / 2) * np.sin(t), linewidth=1.2, color='black') ax.plot(self._fit_coord[0] + (a_90 / 2) * np.cos(t), self._fit_coord[1] + (b_90 / 2) * np.sin(t), linewidth=1.2, color='black') ra_earth = self._earth_circle[0] dec_earth = self._earth_circle[1] earth_angular_radius = self._earth_circle[2] if (ra_earth + earth_angular_radius <= 2 * np.pi) and (ra_earth - earth_angular_radius >= 0): earth_circ = CirclePolygon((ra_earth, dec_earth), earth_angular_radius, resolution=100, antialiased=True, joinstyle='round', facecolor=transp_grey, edgecolor=transp_black, linewidth=1.5, zorder=0) ax.add_patch(earth_circ) else: earth_circ1 = CirclePolygon((ra_earth + np.pi, dec_earth), earth_angular_radius, resolution=100, antialiased=True, joinstyle='round', facecolor=transp_grey, edgecolor=transp_black, linewidth=1.5, zorder=0) ax.add_patch(earth_circ1) earth_circ2 = CirclePolygon((ra_earth - np.pi, dec_earth), earth_angular_radius, resolution=100, antialiased=True, joinstyle='round', facecolor=transp_grey, edgecolor=transp_black, linewidth=1.5, zorder=0) ax.add_patch(earth_circ2) ax.set_xticklabels([ '330$^\circ$', '300$^\circ$', '270$^\circ$', '240$^\circ$', '210$^\circ$', '180$^\circ$', '150$^\circ$', '120$^\circ$', '90$^\circ$', '60$^\circ$', '30$^\circ$' ]) ax.grid() handles, labels = ax.get_legend_handles_labels() legend = ax.legend(handles, labels, loc='lower right') for i, handle in enumerate(legend.legendHandles): if labels[i] == 'Posterior sampling': handle.set_sizes([20]) fig.savefig(self._save_path)
def _make_barbs(self, u, v, nflags, nbarbs, half_barb, empty_flag, length, pivot, sizes, fill_empty, flip): ''' This function actually creates the wind barbs. *u* and *v* are components of the vector in the *x* and *y* directions, respectively. *nflags*, *nbarbs*, and *half_barb*, empty_flag* are, *respectively, the number of flags, number of barbs, flag for *half a barb, and flag for empty barb, ostensibly obtained *from :meth:`_find_tails`. *length* is the length of the barb staff in points. *pivot* specifies the point on the barb around which the entire barb should be rotated. Right now, valid options are 'tip' and 'middle'. Can also be a number, which shifts the start of the barb that many points from the origin. *sizes* is a dictionary of coefficients specifying the ratio of a given feature to the length of the barb. These features include: - *spacing*: space between features (flags, full/half barbs) - *height*: distance from shaft of top of a flag or full barb - *width* - width of a flag, twice the width of a full barb - *emptybarb* - radius of the circle used for low magnitudes *fill_empty* specifies whether the circle representing an empty barb should be filled or not (this changes the drawing of the polygon). *flip* is a flag indicating whether the features should be flipped to the other side of the barb (useful for winds in the southern hemisphere). This function returns list of arrays of vertices, defining a polygon for each of the wind barbs. These polygons have been rotated to properly align with the vector direction. ''' # These control the spacing and size of barb elements relative to the # length of the shaft spacing = length * sizes.get('spacing', 0.125) full_height = length * sizes.get('height', 0.4) full_width = length * sizes.get('width', 0.25) empty_rad = length * sizes.get('emptybarb', 0.15) # Controls y point where to pivot the barb. pivot_points = dict(tip=0.0, middle=-length / 2.) # Check for flip if flip: full_height = -full_height endx = 0.0 try: endy = float(pivot) except ValueError: endy = pivot_points[pivot.lower()] # Get the appropriate angle for the vector components. The offset is # due to the way the barb is initially drawn, going down the y-axis. # This makes sense in a meteorological mode of thinking since there 0 # degrees corresponds to north (the y-axis traditionally) angles = -(ma.arctan2(v, u) + np.pi / 2) # Used for low magnitude. We just get the vertices, so if we make it # out here, it can be reused. The center set here should put the # center of the circle at the location(offset), rather than at the # same point as the barb pivot; this seems more sensible. circ = CirclePolygon((0, 0), radius=empty_rad).get_verts() if fill_empty: empty_barb = circ else: # If we don't want the empty one filled, we make a degenerate # polygon that wraps back over itself empty_barb = np.concatenate((circ, circ[::-1])) barb_list = [] for index, angle in np.ndenumerate(angles): # If the vector magnitude is too weak to draw anything, plot an # empty circle instead if empty_flag[index]: # We can skip the transform since the circle has no preferred # orientation barb_list.append(empty_barb) continue poly_verts = [(endx, endy)] offset = length # Add vertices for each flag for i in range(nflags[index]): # The spacing that works for the barbs is a little to much for # the flags, but this only occurs when we have more than 1 # flag. if offset != length: offset += spacing / 2. poly_verts.extend( [[endx, endy + offset], [endx + full_height, endy - full_width / 2 + offset], [endx, endy - full_width + offset]]) offset -= full_width + spacing # Add vertices for each barb. These really are lines, but works # great adding 3 vertices that basically pull the polygon out and # back down the line for i in range(nbarbs[index]): poly_verts.extend([(endx, endy + offset), (endx + full_height, endy + offset + full_width / 2), (endx, endy + offset)]) offset -= spacing # Add the vertices for half a barb, if needed if half_barb[index]: # If the half barb is the first on the staff, traditionally it # is offset from the end to make it easy to distinguish from a # barb with a full one if offset == length: poly_verts.append((endx, endy + offset)) offset -= 1.5 * spacing poly_verts.extend([(endx, endy + offset), (endx + full_height / 2, endy + offset + full_width / 4), (endx, endy + offset)]) # Rotate the barb according the angle. Making the barb first and # then rotating it made the math for drawing the barb really easy. # Also, the transform framework makes doing the rotation simple. poly_verts = transforms.Affine2D().rotate(-angle).transform( poly_verts) barb_list.append(poly_verts) return barb_list
def draw_cube(cube, cube_name, spots): """ Make a figure and draw cube slices on it spots are a list of [row, col] positions for each spot """ # mask center for better image scaling cube[:, 100:150, 100:150] = np.nan #cube[:,100:150,100:150]*1e-3 chan = 0 nchan = cube.shape[0] # get star positions star_positions = get_single_cube_star_positions(np.array( spots)) #P1640spots.get_single_cube_star_positions(np.array(spots)) #try: fig = plt.figure() fig.suptitle(cube_name, fontsize='x-large') gridsize = (8, 8) """ this was too fancy and just messed things up # scaling ax_radial = plt.subplot2grid(gridsize, (1,6), rowspan=2, colspan=3) ax_radial.plot(np.linalg.norm(np.array(spots) - star_positions, axis=-1).T) ax_radial.set_title("Radial position") ax_radial.grid(True, axis='both', which='major') ax_radial.set_xlabel("channel") ax_radial.set_ylabel("Separation") # centering ax_center = plt.subplot2grid(gridsize, (5,6), rowspan=2, colspan=3) ax_center.set_xlim(np.min(star_positions[:,1])-1, np.max(star_positions[:,1])+1) main image axis object ax = plt.subplot2grid(gridsize, (1,0), rowspan=6, colspan=5) """ ax = fig.add_subplot(111) while True: ax.clear() chan = chan % nchan patches1 = [ CirclePolygon(xy=spot[chan][::-1], radius=5, fill=False, alpha=1, ec='k', lw=2) for spot in spots ] # large circles centered on spot patches2 = [ CirclePolygon(xy=spot[chan][::-1], radius=1, fill=True, alpha=0.3, ec='k', lw=2) for spot in spots ] # dots in location of spot starpatches = [ CirclePolygon(xy=star_positions[chan][::-1], radius=3, fill=True, alpha=0.3, ec='k', lw=2) for spot in spots ] # star position patchcoll = PatchCollection(patches1 + patches2, match_original=True) imax = ax.imshow(cube[chan], norm=LogNorm()) imax.axes.add_collection(patchcoll) ax.set_title("Channel {1:02d}".format(cube_name, chan)) """ ax_center.set_title("Star position") ax_center.plot(star_positions[:,1], star_positions[:,0], 'b-') ax_center.plot(star_positions[chan,1], star_positions[chan,0], 'bx', ms=10, mew=2) ax_center.grid(True, axis='both', which='major') ax_center.set_xlabel("x") ax_center.set_ylabel("y") """ plt.pause(0.2) chan += 1
def display_mc_2x2(self): """Plot the moment curvature, and interactive section viewer""" # TODO SEPARATE PLOT FOR FORCE/STRESS DISTRIBUTION? # TODO PATCH COLLECTION FOR INSTANTANEOUS? COLOR UPDATE? fig, axes = plt.subplots(2, 2, figsize=(self.figsize * 1.5, self.figsize * 1.5)) ax = axes[0, 0] ax_mc = axes[0, 1] ax_strain = axes[1, 0] ax_stress = axes[1, 1] polygons = [] for e in self.mesh.elements: poly_pts = [self.mesh.points[i] for i in e] polygons.append(poly_pts) patches = [] # Draw Polygons for mesh and reinformcent i = 0 for p in polygons: new_patch = plt.Polygon(p, fc=(0.8, 0.8, 0.8), ec='black', zorder=0, picker=.01, gid=str(i)) patches.append(new_patch) ax.add_patch(new_patch) i += 1 if self.reinforcement: for reinf_group in self.reinforcement: for centroid in reinf_group.points: new_patch = CirclePolygon(centroid, reinf_group.radius, 8, fc='White', ec='black', zorder=15, picker=.01, gid=str(i)) patches.append(new_patch) ax.add_patch(new_patch) i += 1 # Plot nodal points of mesh (useful to auto set axes limts) ax.scatter(*zip(*self.mesh.points), c='black', s=4, zorder=5) num_steps = len(self.states) - 1 # LEFT MC Plot ax_mc.plot(self.phi_list, self.M_list, 'k') ax.axis('equal') # Location indicator as patch so we can update it easily # Ellipse b/c we don't have equal axis ranges for phi/M point = Ellipse((0, 0), max(self.phi_list) / 50, max(self.M_list) / 50, fc='red', zorder=10) ax_mc.add_patch(point) # Scientific notation for phi values ax_mc.ticklabel_format(axis='x', style='sci', scilimits=(-2, 2), useMathText=True) # Setup Sliders for interatablility to look through results def update(phi_step): phi_step = int(phi_step) self.state_id = int(phi_step) # Update Patch colors state_colors = [ self.color_from_state(e) for e in self.states[phi_step].mat_state ] for patch, color in zip(patches, state_colors): patch.set_facecolor(color) point.center = (self.phi_list[phi_step], self.M_list[phi_step]) x = [ self.states[phi_step].min_strain, self.states[phi_step].max_strain ] y = [self.analysis_model.miny, self.analysis_model.maxy] global line, line2, line3 line.set_data(x, y) line2.set_data( [-1, 1], [self.states[phi_step].yloc, self.states[phi_step].yloc]) line3.set_data([ self.analysis_model.miny * 1.1, self.analysis_model.maxy * 1.1 ], [self.states[phi_step].yloc, self.states[phi_step].yloc]) fig.canvas.draw_idle() # Setup mesh onclick event to view stress/strain location of each fiber def onpick(event): #print(event.mouseevent.__dict__) #print(event.artist.__dict__) #print(event.canvas.__dict__) patch_id = int(event.artist._gid) strain = self.states[self.state_id].strains[patch_id] stress = self.states[self.state_id].stresses[patch_id] self.display_materials(self.ele_mat[patch_id], (strain, stress)) return True fig.canvas.mpl_connect('pick_event', onpick) ax_slider = plt.axes([0.117, 0.01, 0.79, 0.02], facecolor='white') slider_fct = Slider(ax_slider, 'STEP', 0, num_steps, valinit=0, valstep=1, valfmt='%i') slider_fct.on_changed(update) # Strain plot ax_strain.plot([0, 0], [self.analysis_model.miny, self.analysis_model.maxy], 'k') ax_strain.set_xlim([ self.states[len(self.states) - 1].min_strain * 1.05, self.states[len(self.states) - 1].max_strain * 1.05 ]) global line, line2, line3 line, = ax_strain.plot( [0, 0], [self.analysis_model.miny, self.analysis_model.maxy], color='Red') phi_step = 0 line2, = ax_strain.plot( [-1, 1], [self.states[phi_step].yloc, self.states[phi_step].yloc], color='Blue') line3, = ax.plot( [self.analysis_model.miny * 1.1, self.analysis_model.maxy * 1.1], [self.states[phi_step].yloc, self.states[phi_step].yloc], color='Red') # Stress Plot ax_stress.plot([0, 0], [self.analysis_model.miny, self.analysis_model.maxy], 'k') ax_stress.text(0, 0, "This Plot Was\nIntentionally Left Blank\n(For Now)") plt.tight_layout(rect=(0, .05, 1, 1)) plt.show()
def mc_gif(self): """Testing saving as gif""" fig, (ax, ax_mc) = plt.subplots(1, 2, figsize=(self.figsize * 2, self.figsize)) polygons = [] for e in self.mesh.elements: poly_pts = [self.mesh.points[i] for i in e] polygons.append(poly_pts) patches = [] # Draw Polygons for mesh and reinformcent i = 0 for p in polygons: new_patch = plt.Polygon(p, fc='Grey', ec='Black', zorder=0, picker=.01, gid=str(i)) patches.append(new_patch) ax.add_patch(new_patch) i += 1 if self.reinforcement: for reinf_group in self.reinforcement: for centroid in reinf_group.points: new_patch = CirclePolygon(centroid, reinf_group.radius, 8, fc='White', ec='Black', zorder=15, picker=.01, gid=str(i)) patches.append(new_patch) ax.add_patch(new_patch) i += 1 # Plot nodal points of mesh (useful to auto set axes limts) ax.scatter(*zip(*self.mesh.points), c='black', s=4, zorder=5) num_steps = len(self.states) - 1 # LEFT MC Plot ax_mc.plot(self.phi_list, self.M_list, 'k') ax.axis('equal') # Location indicator as patch so we can update it easily # Ellipse b/c we don't have equal axis ranges for phi/M point = Ellipse((0, 0), max(self.phi_list) / 50, max(self.M_list) / 50, fc='red', zorder=10) ax_mc.add_patch(point) # Scientific notation for phi values ax_mc.ticklabel_format(axis='x', style='sci', scilimits=(-2, 2), useMathText=True) # Setup Sliders for interatablility to look through results def update(state): state = int(state) self.state_id = int(state) # Update Patch colors state_colors = [ self.color_from_state(e) for e in self.states[state].mat_state ] for patch, color in zip(patches, state_colors): patch.set_facecolor(color) point.center = (self.phi_list[state], self.M_list[state]) #fig.canvas.draw_idle() ax_slider = plt.axes([0.117, 0.01, 0.79, 0.02], facecolor='White') slider_fct = Slider(ax_slider, 'STEP', 0, num_steps, valinit=0, valstep=1, valfmt='%i') slider_fct.on_changed(update) def frame(state): # Set State - Updates everything slider_fct.set_val(state) print( "Saving animated gif. This will take a while and take several dozen megs of space.\nIt's saving full frames and not optimizing." ) test = anim.FuncAnimation(fig, frame, frames=range(len(self.states))) test.save("Moment_Curvature.gif", fps=16)
def patch_func(legend, orig_handle, xdescent, ydescent, width, height, fontsize): radius = width / 2 return CirclePolygon((radius - xdescent, height / 2 - ydescent), radius)
self.line.set_data(zip(*self.poly.verts)) self.canvas.restore_region(self.background) self.ax.draw_artist(self.poly) self.ax.draw_artist(self.line) self.canvas.blit(self.ax.bbox) from pylab import * fig = figure() circ = CirclePolygon((.5,.5),.5, animated=True) ax = subplot(111) ax.add_patch(circ) p = PolygonInteractor( ax, circ) ax.add_line(p.line) ax.set_title('Click and drag a point to move it') ax.set_xlim((0,1)) ax.set_ylim((0,1)) show()
precip.data = qcut(precip.data.flatten(), 100, labels=False, duplicates='drop').reshape(s) pmin = numpy.min(precip.data) pmax = numpy.max(precip.data) p_interpolator = iris.analysis.Linear().interpolator(precip, ['latitude', 'longitude']) # Generate a set of points to plot at p_points = mg.wind.allocate_vector_points(scale=0.25, max_points=1000000) #, # lat_range=(-45,45),lon_range=(75,165)) p_lats = p_points['Latitude'] p_lons = p_points['Longitude'] # Plot them on the map #patches = [] for p_i in range(len(p_points['Longitude'])): p_at = p_interpolator([p_lats[p_i], p_lons[p_i]]).data shade = max(0, min(1, p_at / pmax)) circle = CirclePolygon( (p_points['Longitude'][p_i], p_points['Latitude'][p_i]), radius=max(0, 0.25 * min(1, p_at / pmax)), edgecolor=(0, 0.3, 0, shade), facecolor=(0, 0.3, 0, shade), linewidth=0, fill=True, zorder=500) p = ax.add_patch(circle) # Render the figure as a png fig.savefig('precip_points.png')