def scatter(self, x, y, s=20, c='b', marker='o', cmap=None, norm=None, vmin=None, vmax=None, alpha=1.0, linewidths=None, faceted=True, verts=None, **kwargs): """ SCATTER(x, y, s=20, c='b', marker='o', cmap=None, norm=None, vmin=None, vmax=None, alpha=1.0, linewidths=None, faceted=True, **kwargs) Supported function signatures: SCATTER(x, y) - make a scatter plot of x vs y SCATTER(x, y, s) - make a scatter plot of x vs y with size in area given by s SCATTER(x, y, s, c) - make a scatter plot of x vs y with size in area given by s and colors given by c SCATTER(x, y, s, c, **kwargs) - control colormapping and scaling with keyword args; see below Make a scatter plot of x versus y. s is a size in points^2 a scalar or an array of the same length as x or y. c is a color and can be a single color format string or an length(x) array of intensities which will be mapped by the matplotlib.colors.colormap instance cmap The marker can be one of 's' : square 'o' : circle '^' : triangle up '>' : triangle right 'v' : triangle down '<' : triangle left 'd' : diamond 'p' : pentagram 'h' : hexagon '8' : octagon if marker is None and verts is not None, verts is a sequence of (x,y) vertices for a custom scatter symbol. The s is a size argument in points squared. Any or all of x, y, s, and c may be masked arrays, in which case all masks will be combined and only unmasked points will be plotted. Other keyword args; the color mapping and normalization arguments will on be used if c is an array of floats * cmap = cm.jet : a cm Colormap instance from matplotlib.cm. defaults to rc image.cmap * norm = normalize() : matplotlib.colors.normalize is used to scale luminance data to 0,1. * vmin=None and vmax=None : vmin and vmax are used in conjunction with norm to normalize luminance data. If either are None, the min and max of the color array C is used. Note if you pass a norm instance, your settings for vmin and vmax will be ignored * alpha =1.0 : the alpha value for the patches * linewidths, if None, defaults to (lines.linewidth,). Note that this is a tuple, and if you set the linewidths argument you must set it as a sequence of floats, as required by RegularPolyCollection -- see matplotlib.collections.RegularPolyCollection for details * faceted: if True, will use the default edgecolor for the markers. If False, will set the edgecolors to be the same as the facecolors """ if not self._hold: self.cla() syms = { # a dict from symbol to (numsides, angle) 's' : (4, math.pi/4.0), # square 'o' : (20, 0), # circle '^' : (3,0), # triangle up '>' : (3,math.pi/2.0), # triangle right 'v' : (3,math.pi), # triangle down '<' : (3,3*math.pi/2.0), # triangle left 'd' : (4,0), # diamond 'p' : (5,0), # pentagram 'h' : (6,0), # hexagon '8' : (8,0), # octagon } x, y, s, c = delete_masked_points(x, y, s, c) if kwargs.has_key('color'): c = kwargs['color'] kwargs.pop('color') if not is_string_like(c) and iterable(c) and len(c)==len(x): colors = None else: colors = ( colorConverter.to_rgba(c, alpha), ) if not iterable(s): scales = (s,) else: scales = s if faceted: edgecolors = None else: edgecolors = 'None' sym = None lns = None verts = None if isinstance(marker, str) or isinstance(marker, unicode): # the standard way using marker=character sym = syms.get(marker) if sym is None: raise ValueError('Unknown marker symbol to scatter') numsides, rotation = syms[marker] elif hasattr(marker,'__len__'): # marker may additionally be: # (numsides, style, [angle]) # or # (verts, style, [angle]) if len(marker)<2: raise ValueError('Cannot create markersymbol') if isinstance(marker[0], int): if marker[1]==0: # solid symbols if len(marker)==2: # numsides, style numsides, rotation = marker[0], math.pi/4. sym = True elif len(marker)==3: # numsides, style, angle numsides, rotation = marker[0], marker[2] sym = True elif marker[1]==1 or marker[1]==2: # 1: skeletal symbols # 2: stared symbols raise('Not yet implemented') if len(marker)==2: numsides, rotation, style = marker[0], math.pi/4., marker[1] lns = True else: verts = asarray(marker[0]) if verts.shape[1] != 2: raise ValueError('Cannot create markersymbol, give correct verts') if sym is None and lns is None and verts is None: raise ValueError('Unknown marker symbol to scatter') if sym is not None: collection = RegularPolyCollection( self.figure.dpi, numsides, rotation, scales, facecolors = colors, edgecolors = edgecolors, linewidths = linewidths, offsets = zip(x,y), transOffset = self.transData, ) elif lns is not None: pass #collection = RegularLineCollection( # [...], # style = # ) else: # first rescale verts rescale = sqrt(max(verts[:,0]**2+verts[:,1]**2)) verts /= rescale scales = asarray(scales) scales = sqrt(scales * self.figure.dpi.get() / 72.) if len(scales)==1: verts = [scales[0]*verts] else: # todo -- make this nx friendly verts = [verts*s for s in scales] collection = PolyCollection( verts, facecolors = colors, edgecolors = edgecolors, linewidths = linewidths, offsets = zip(x,y), transOffset = self.transData, ) collection.set_transform(identity_transform()) collection.set_alpha(alpha) collection.update(kwargs) if colors is None: if norm is not None: assert(isinstance(norm, normalize)) if cmap is not None: assert(isinstance(cmap, Colormap)) collection.set_array(asarray(c)) collection.set_cmap(cmap) collection.set_norm(norm) if vmin is not None or vmax is not None: collection.set_clim(vmin, vmax) else: collection.autoscale() minx = amin(x) maxx = amax(x) miny = amin(y) maxy = amax(y) w = maxx-minx h = maxy-miny # the pad is a little hack to deal with the fact that we don't # want to transform all the symbols whose scales are in points # to data coords to get the exact bounding box for efficiency # reasons. It can be done right if this is deemed important padx, pady = 0.05*w, 0.05*h corners = (minx-padx, miny-pady), (maxx+padx, maxy+pady) self.update_datalim( corners) self.autoscale_view() # add the collection last self.add_collection(collection) return collection