def quadface(self, axes=None, show=False, figsize=None, **kwargs): if len(self.quads) > 0: pc = PolyCollection(self.coords[self.quads], **kwargs) quad_value = np.mean(self.values[self.quads], axis=1) pc.set_array(quad_value) axes.add_collection(pc) return axes
def init_plots(self): xc = p.um * cells.cell_centres[:, 0] yc = p.um * cells.cell_centres[:, 1] xm = p.um * cells.mem_mids_flat[:, 0] ym = p.um * cells.mem_mids_flat[:, 1] xec = p.um * cells.ecm_mids[:, 0] yec = p.um * cells.ecm_mids[:, 1] xenv = p.um * cells.xypts[:, 0] yenv = p.um * cells.xypts[:, 1] xyaxis = [p.um * cells.xmin, p.um * cells.xmax, p.um * cells.ymin, p.um * cells.ymax] verts = p.um * cells.cell_verts fig = plt.figure() ax = plt.subplot(111) col = PolyCollection(verts, cmap='RdBu_r') col.set_array(cA_time[-1]) ax.add_collection(col) fig.colorbar(col) plt.axis('equal') plt.axis(xyaxis) plt.show()
def cell_mosaic( data, ax: 'matplotlib.axes.Axes', cells: 'Cells', p: 'Parameters', clrmap: 'matplotlib.colors.Colormap', ) -> (PolyCollection, 'matplotlib.axes.Axes'): """ Sets up a mosaic plot for cell data on an existing axis. Parameters ----------- data Data defined on environmental grid cells Instance of cells module p Instance of parameters module ax Existing figure axis to plot currents on Returns -------- collection Container for mosaic plot ax Modified axis """ # define a polygon collection based on individual cell polygons points = np.multiply(cells.cell_verts, p.um) collection = PolyCollection(points, cmap=clrmap, edgecolors='none') collection.set_array(data) ax.add_collection(collection) return collection, ax
def plotcelldata(self, z, xlims=None, ylims=None, colorbar=True, **kwargs): """ Plot cell centered data """ ax=plt.gca() fig = plt.gcf() # Find the colorbar limits if unspecified if self.clim is None: self.clim = [z.min(),z.max()] # Set the xy limits if xlims is None or ylims is None: xlims=self.xlims() ylims=self.ylims() collection = PolyCollection(self.xy(),closed=False,**kwargs) collection.set_array(z) collection.set_clim(vmin=self.clim[0],vmax=self.clim[1]) collection.set_edgecolors(collection.to_rgba(z)) ax.add_collection(collection) ax.set_aspect('equal') ax.set_xlim(xlims) ax.set_ylim(ylims) axcb=None if colorbar: axcb = fig.colorbar(collection) return fig, ax, collection, axcb
def plotcelldata(self, z, xlims=None, ylims=None, colorbar=True, **kwargs): """ Plot cell centered data """ ax = plt.gca() fig = plt.gcf() # Find the colorbar limits if unspecified if self.clim is None: self.clim = [z.min(), z.max()] # Set the xy limits if xlims is None or ylims is None: xlims = self.xlims() ylims = self.ylims() collection = PolyCollection(self.xy(), closed=False, **kwargs) collection.set_array(z) collection.set_clim(vmin=self.clim[0], vmax=self.clim[1]) collection.set_edgecolors(collection.to_rgba(z)) ax.add_collection(collection) ax.set_aspect('equal') ax.set_xlim(xlims) ax.set_ylim(ylims) axcb = None if colorbar: axcb = fig.colorbar(collection) return fig, ax, collection, axcb
def plot_poly_collection(ax, verts, zs=None, color=None, cmap=None, vmin=None, vmax=None, **kwargs): from matplotlib.collections import PolyCollection # if None in zs: # zs = None # color=None overwrites specified facecolor/edgecolor with default color if color is not None: kwargs["color"] = color import matplotlib as mpl norm = mpl.colors.Normalize(vmin=vmin, vmax=vmax) poly = PolyCollection(verts, **kwargs) if zs is not None: poly.set_array(np.asarray(zs)) poly.set_cmap(cmap) poly.set_clim(vmin, vmax) ax.add_collection3d(poly, zs=zs, zdir="y") # ax.autoscale_view() return poly
def makesubplot_imageGrid(ax, data, cLatdata, cLondata, colorlimits, fill): m = Basemap(width=2400000, height=1500000, resolution='l', projection='laea', lat_0=56., lon_0=40.) m.drawcoastlines() m.drawmapboundary() m.bluemarble() m.drawcountries(linewidth=1) m.drawparallels(np.arange(-90., 91., 5.), labels=[False, True, True, False], fontsize=8) m.drawmeridians(np.arange(-180., 180., 10.), labels=[True, False, False, True], fontsize=8) conv = [] for xi, i in enumerate(data): lats = [ cLatdata[xi][0], cLatdata[xi][1], cLatdata[xi][2], cLatdata[xi][3] ] lons = [ cLondata[xi][0], cLondata[xi][1], cLondata[xi][2], cLondata[xi][3] ] mlats, mlons = m(lons, lats) conv.append([mlats, mlons, i[2]]) conv = np.array(conv) convPoly = [] for i in conv: convPoly.append(list(zip(i[0], i[1]))) if fill: ConvColl = PolyCollection(convPoly, array=conv[:, 2], edgecolor='none', cmap=mpl.cm.jet) im = ax.add_collection(ConvColl) ConvColl.set_array(conv[:, 2]) if colorlimits: ConvColl.set_clim(colorlimits) else: ConvColl = PolyCollection(convPoly, edgecolor=(1, 1, 1, 1), facecolor=(1, 1, 1, 0), cmap=mpl.cm.jet) im = ax.add_collection(ConvColl) return im
def _ax_plot(self, *, ax, mesh, val: np.ndarray = None, **kwargs): """ Set coordinates, connectivity and values to plot Parameters ---------- mesh : Mesh class val : ndarray Value to plot in each element [n_element] (1D array) xlim : array-like Range of x-axis ylim : array-like Range of y-axis cmap : str Color map edgecolor : str Edge color lw : int Line width Returns ------- ax : Axis pcm : PolyCollection """ ax = self._set_window(ax, mesh.coords, **kwargs) vertices = mesh.coords[:2, :].T[np.asarray(mesh.connectivity)] if "edgecolor" not in kwargs: kwargs["edgecolor"] = "k" if "lw" not in kwargs: kwargs["lw"] = 1 if "cmap" not in kwargs: kwargs["cmap"] = "rainbow" self._delete_plt_unnecessary_keys(kwargs) if val is None: pcm = PolyCollection(vertices, facecolor="None", **kwargs) else: pcm = PolyCollection(vertices, **kwargs) value = np.array(val) if value.shape[0] != mesh.n_element: logger = getLogger("viewer2d") logger.error( "Value arrray has invalid size. Size of values: {}, Number of elements: {}".format( value.shape[0], mesh.n_element ) ) sys.exit(1) pcm.set_array(value) ax.add_collection(pcm) return ax, pcm
def overlay_gridsquare_data(self, gridsquares, data, cmap=None, vmin=None, vmax=None, zorder=99, plot_cbar=True, cbar_label=None, cbar_ticks=None, cbar_shrink=0.7): """ Overlay gridsquare data on a map. """ if cmap is None: cmap = matplotlib.cm.jet if vmin is None: vmin = np.min(data) if vmax is None: vmax = np.max(data) ll = locator.gridsquare2latlon lats_ll, lons_ll = ll(gridsquares, 'lower left') lats_lr, lons_lr = ll(gridsquares, 'lower right') lats_ur, lons_ur = ll(gridsquares, 'upper right') lats_ul, lons_ul = ll(gridsquares, 'upper left') coords = zip(lats_ll, lons_ll, lats_lr, lons_lr, lats_ur, lons_ur, lats_ul, lons_ul) verts = [] for lat_ll, lon_ll, lat_lr, lon_lr, lat_ur, lon_ur, lat_ul, lon_ul in coords: x1, y1 = self.m(lon_ll, lat_ll) x2, y2 = self.m(lon_lr, lat_lr) x3, y3 = self.m(lon_ur, lat_ur) x4, y4 = self.m(lon_ul, lat_ul) verts.append(((x1, y1), (x2, y2), (x3, y3), (x4, y4), (x1, y1))) vals = data bounds = np.linspace(vmin, vmax, 256) norm = matplotlib.colors.BoundaryNorm(bounds, cmap.N) pcoll = PolyCollection(np.array(verts), edgecolors='face', closed=False, cmap=cmap, norm=norm, zorder=zorder) pcoll.set_array(np.array(vals)) self.ax.add_collection(pcoll, autolim=False) if plot_cbar: cbar = self.fig.colorbar(pcoll, label=cbar_label, shrink=cbar_shrink) if cbar_ticks is not None: cbar.set_ticks(cbar_ticks) return pcoll
def plot_mic_patches(self, plotType, minConfidence): indx = self.snp[:, 9] >= minConfidence minsw = self.sw / float(2**self.snp[0, 4]) tsw1 = minsw * 0.5 tsw2 = -minsw * 0.5 * 3**0.5 ntri = len(self.snp) if plotType == 2: fig, ax = plt.subplots() if self.bpatches == False: xy = self.snp[:, :2] tmp = np.asarray([[tsw1] * ntri, (-1)**self.snp[:, 3] * tsw2]).transpose() tris = np.asarray([[[0, 0]] * ntri, [[minsw, 0]] * ntri, tmp]) self.patches = np.swapaxes(tris + xy, 0, 1) self.bpatches = True p = PolyCollection(self.patches[indx], cmap='viridis') p.set_array(self.color2[indx]) p.set_edgecolor('face') ax.add_collection(p) ax.set_xlim([-0.6, 0.6]) ax.set_ylim([-0.6, 0.6]) fig.colorbar(p, ax=ax) plt.show() if plotType == 1: fig, ax = plt.subplots() N = len(self.snp) mat = np.empty([N, 3, 3]) quat = np.empty([N, 4]) rod = np.empty([N, 3]) if self.bcolor1 == False: for i in range(N): mat[i, :, :] = RotRep.EulerZXZ2Mat(self.snp[i, 6:9] / 180.0 * np.pi) quat[i, :] = RotRep.quaternion_from_matrix(mat[i, :, :]) rod[i, :] = RotRep.rod_from_quaternion(quat[i, :]) self.color1 = (rod + np.array([1, 1, 1])) / 2 self.bcolor1 = True if self.bpatches == False: xy = self.snp[:, :2] tmp = np.asarray([[tsw1] * ntri, (-1)**self.snp[:, 3] * tsw2]).transpose() tris = np.asarray([[[0, 0]] * ntri, [[minsw, 0]] * ntri, tmp]) self.patches = np.swapaxes(tris + xy, 0, 1) self.bpatches = True p = PolyCollection(self.patches[indx], cmap='viridis') p.set_color(self.color1[indx]) ax.add_collection(p) ax.set_xlim([-0.6, 0.6]) ax.set_ylim([-0.6, 0.6]) plt.show()
def plot_trimesh2D(verts, faces, val=None, cmap=plt.cm.get_cmap(), vmin=None, vmax=None, mirror=False, **kw): """Plot a mesh of triangles, from directly above, without all this 3D stuff. Input verts N x 3 array of vertex locations faces M x 3 array of vertex indices for each face val M list of values for each vertex, used for coloring cmap colormap, defaulting to current colormap vmin lower limit for coloring, defaulting to min(val) vmax upper limit for coloring, defaulting to max(val) mirror flag for mirror around x=0 Other keyword pairs are passed to PolyCollection """ v = array([[verts[ind, :2] for ind in face] for face in faces]) if mirror: v = r_[v, v * [-1, 1]] if val is not None: val = array(val) poly = PolyCollection(v, cmap=cmap, norm=Normalize(clip=True), **kw) poly.set_array(val) poly.set_clim(vmin, vmax) poly.set_facecolors(poly.norm(val)) ax = plt.gca() ax.add_collection(poly) ax.axis('image') if val is not None: # This magic dohickey is used by colorbar() and clim(), for example plt.gci._current = poly plt.draw() # Seems like should be draw_if_interactive(), but that doesn't # work, for some unexplained reason. return poly
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()
def make_patches(xdata, ydata, zdata, cmap_name='viridis'): """Make some patches for multi-coloring the area under a curve. Parameters ---------- xdata : list or array_like The x positions for the curve. ydata : list or array_like The y positions for the curve. zdata : list or array_like A list of values associated with each point, used for coloring. cmap_name : string, optional The name of the color map to use. Returns ------- poly : object like :py:class:`matplotlib.collections.PolyCollection` The polygons created here, with individual colors. cmap : object like :py:class:`matplotlib.colors.ListedColormap` The created color map. norm : object like :py:class:`matplotlib.colors.Normalize` The created normalization for the data. """ cmap, norm = _select_cmap(zdata, cmap_name) verts = [] for i, (xval, yval) in enumerate(zip(xdata, ydata)): if i == 0: xnext = 0.5 * (xdata[i + 1] + xval) ynext = 0.5 * (ydata[i + 1] + yval) verts.append([[xval, 0], [xval, yval], [xnext, ynext], [xnext, 0]]) elif i == len(xdata) - 1: xprev = 0.5 * (xval + xdata[i - 1]) yprev = 0.5 * (yval + ydata[i - 1]) verts.append([[xprev, 0], [xprev, yprev], [xval, yval], [xval, 0]]) else: xnext = 0.5 * (xdata[i + 1] + xval) ynext = 0.5 * (ydata[i + 1] + yval) xprev = 0.5 * (xval + xdata[i - 1]) yprev = 0.5 * (yval + ydata[i - 1]) verts.append([[xprev, 0], [xprev, yprev], [xval, yval], [xnext, ynext], [xnext, 0]]) poly = PolyCollection(verts, cmap=cmap, norm=norm) poly.set_array(zdata) return poly, cmap, norm
def plot_trimesh2D(verts, faces, val=None, cmap=plt.cm.get_cmap(), vmin=None, vmax=None, mirror=False, **kw): """Plot a mesh of triangles, from directly above, without all this 3D stuff. Input verts N x 3 array of vertex locations faces M x 3 array of vertex indices for each face val M list of values for each vertex, used for coloring cmap colormap, defaulting to current colormap vmin lower limit for coloring, defaulting to min(val) vmax upper limit for coloring, defaulting to max(val) mirror flag for mirror around x=0 Other keyword pairs are passed to PolyCollection """ v = array([[verts[ind,:2] for ind in face] for face in faces]) if mirror: v = r_[v, v * [-1,1]] if val is not None: val = array(val) poly = PolyCollection(v, cmap=cmap, norm=Normalize(clip=True), **kw) poly.set_array(val) poly.set_clim(vmin, vmax) poly.set_facecolors(poly.norm(val)) ax = plt.gca() ax.add_collection(poly) ax.axis('image') if val is not None: # This magic dohickey is used by colorbar() and clim(), for example plt.gci._current = poly plt.draw() # Seems like should be draw_if_interactive(), but that doesn't # work, for some unexplained reason. return poly
def plot2dscales(self, verts, area2, scale2): fig = plt.figure() ax1 = fig.add_subplot(221) ax2 = fig.add_subplot(222) ax3 = fig.add_subplot(223) ax4 = fig.add_subplot(224) poly2d1 = PolyCollection(verts) poly2d1.set_array(np.array(area2) / max(area2)) poly2d2 = PolyCollection(verts) poly2d2.set_array(np.array(scale2) / max(scale2)) poly2d3 = PolyCollection(verts) poly2d3.set_array(np.array(self.total_scale) / max(self.total_scale)) poly2d4 = PolyCollection(verts) poly2d4.set_array(self.required_pe * np.array(self.total_scale) / max(self.total_scale)) lim = max(self.geom.pix_x).value ax1.add_collection(poly2d1) ax1.set_xlim(-lim, lim) ax1.set_ylim(-lim, lim) ax1.set_xlabel('X') ax1.set_ylabel('Y') ax1.set_title('Geometry Scale') ax2.add_collection(poly2d2) ax2.set_xlim(-lim, lim) ax2.set_ylim(-lim, lim) ax2.set_xlabel('X') ax2.set_ylabel('Y') ax2.set_title('Angular Pulse Scale') ax3.add_collection(poly2d3) ax3.set_xlim(-lim, lim) ax3.set_ylim(-lim, lim) ax3.set_xlabel('X') ax3.set_ylabel('Y') ax3.set_title('Total Scale') ax4.add_collection(poly2d4) ax4.set_xlim(-lim, lim) ax4.set_ylim(-lim, lim) ax4.set_xlabel('X') ax4.set_ylabel('Y') ax4.set_title('p.e. per pixel') fig.colorbar(poly2d1, ax=ax1) fig.colorbar(poly2d2, ax=ax2) fig.colorbar(poly2d3, ax=ax3) fig.colorbar(poly2d4, ax=ax4)
def plotSolution(self, heatExch, axes, var, zmin=None, zmax=None, cmap=cm.jet): vertexIDs = self.mesh._orderedCellVertexIDs vertexCoords = self.mesh.vertexCoords xCoords = np.take(vertexCoords[0], vertexIDs) yCoords = np.take(vertexCoords[1], vertexIDs) polys = [] for x, y in zip(xCoords.swapaxes(0, 1), yCoords.swapaxes(0, 1)): if hasattr(x, 'mask'): x = x.compressed() if hasattr(y, 'mask'): y = y.compressed() polys.append(zip(x, y)) from matplotlib.collections import PolyCollection # Set limits xmin = xCoords.min() xmax = xCoords.max() ymin = yCoords.min() ymax = yCoords.max() axes.set_xlim(xmin=xmin, xmax=xmax) axes.set_ylim(ymin=ymin, ymax=ymax) Z = var.value if (zmin is None): zmin = np.min(Z) if (zmax is None): zmax = np.max(Z) norm = Normalize(zmin, zmax) collection = PolyCollection(polys, cmap=cmap, norm=norm) collection.set_linewidth(0.) axes.add_collection(collection) cbax, _ = colorbar.make_axes(axes) cb = colorbar.ColorbarBase(cbax, cmap=cmap, norm=norm) cb.set_label('Temperature [K]') collection.set_array(np.array(Z))
def main_2d(vertices, faces, facecolors, edges, edgecolors, verts, vertexcolors, args, canvassize=4): fig = plt.figure() fig.set_size_inches(canvassize, canvassize) ax = fig.add_subplot(111) ax.set_aspect("equal") plt.axis('off') these_faces = [vertices[i] for i in faces] pd = PolyCollection(these_faces, edgecolors=edgecolors) try: pd.set_facecolor(facecolors) except ValueError: pd.set_array(np.array(facecolors)) pd.set_cmap(plt.get_cmap(args.cmap)) ax.add_collection(pd) these_edges = vertices[edges] ld = LineCollection(these_edges, edgecolor=edgecolors) ax.add_collection(ld) these_vertices = vertices[verts] ax.scatter(these_vertices[..., 0], these_vertices[..., 1], c=vertexcolors)
def plotSolution(self, heatExch, axes, var, zmin = None, zmax = None, cmap = cm.jet): vertexIDs = self.mesh._orderedCellVertexIDs vertexCoords = self.mesh.vertexCoords xCoords = np.take(vertexCoords[0], vertexIDs) yCoords = np.take(vertexCoords[1], vertexIDs) polys = [] for x, y in zip(xCoords.swapaxes(0,1), yCoords.swapaxes(0,1)): if hasattr(x, 'mask'): x = x.compressed() if hasattr(y, 'mask'): y = y.compressed() polys.append(zip(x,y)) from matplotlib.collections import PolyCollection # Set limits xmin = xCoords.min() xmax = xCoords.max() ymin = yCoords.min() ymax = yCoords.max() axes.set_xlim(xmin=xmin, xmax=xmax) axes.set_ylim(ymin=ymin, ymax=ymax) Z = var.value if (zmin is None): zmin = np.min(Z) if (zmax is None): zmax = np.max(Z) norm = Normalize(zmin, zmax) collection = PolyCollection(polys, cmap = cmap, norm = norm) collection.set_linewidth(0.) axes.add_collection(collection) cbax, _ = colorbar.make_axes(axes) cb = colorbar.ColorbarBase(cbax, cmap=cmap, norm = norm) cb.set_label('Temperature [K]') collection.set_array(np.array(Z))
vert4 = [boundary.west_edge, boundary.south_edge] return np.array([vert1, vert2, vert3, vert4]) DPI = 72 fig = plt.figure(figsize=(700 / DPI, 500 / DPI), dpi=DPI) ax = plt.subplot() ax.set_xlim(LEFT, RIGHT) ax.set_ylim(BOTTOM, TOP) # Get the boxes for the valid comparisons verts_valid = [get_polygon(bound) for i,bound in enumerate(C) \ if not C_masked.mask[i]] C_valid = [C_masked.data[i] for i in range(len(C)) if not C_masked.mask[i]] c = PolyCollection(verts_valid) c.set_array(C_masked) c.set_cmap(colormap) # ax.add_collection(c) # Get the boxes for absent actual data verts_invalid = [get_polygon(bound) for i,bound in enumerate(C) \ if C_masked.mask[i]] c = PolyCollection(verts_invalid, hatch=r"./", facecolor='white') ax.add_collection(c) # Draw the box partitions qtree.draw(ax) for area in area_data: plot_gdf(ax, area_data[area]['df_lines'], area_data[area]['df_buses'], 'orangered')
def makeplot_polygon(fig, data, cLatdata, cLondata, colorlimits, fill): ax = fig.add_subplot(111) m = Basemap(width=4200000, height=2100000, resolution='l', projection='stere', lat_ts=20, lat_0=55., lon_0=40.) m.drawcoastlines() m.drawmapboundary() m.bluemarble() m.drawcountries(linewidth=1) m.drawparallels(np.arange(-90., 91., 5), labels=[False, True, True, False], fontsize=8) m.drawmeridians(np.arange(-180., 180., 5), labels=[True, False, False, True], fontsize=8) conv = [] for xi, i in enumerate(data): lats = [ cLatdata[xi][0], cLatdata[xi][1], cLatdata[xi][2], cLatdata[xi][3] ] lons = [ cLondata[xi][0], cLondata[xi][1], cLondata[xi][2], cLondata[xi][3] ] mlats, mlons = m(lons, lats) conv.append([mlats, mlons, i[2]]) conv = np.array(conv) convPoly = [] for i in conv: convPoly.append(zip(i[0], i[1])) if fill: ConvColl = PolyCollection(convPoly, array=conv[:, 2], edgecolor='black', cmap=mpl.cm.jet) ax.add_collection(ConvColl) ConvColl.set_array(conv[:, 2]) ConvColl.set_clim(colorlimits) else: ConvColl = PolyCollection(convPoly, edgecolor=(1, 1, 1, 1), facecolor=(1, 1, 1, 0), cmap=mpl.cm.jet) ax.add_collection(ConvColl) # ConvColl.set_array(conv[:,2]) # cb = plt.colorbar(ConvColl, shrink=0.5,orientation="horizontal") return ax, ConvColl
tri = Tri.Triangulation(xnode, ynode, triangles=nv) # make a PolyCollection using triangles verts = concatenate((tri.x[tri.triangles][..., None], tri.y[tri.triangles][..., None]), axis=2) collection = PolyCollection(verts) collection.set_edgecolor('none') # <codecell> timestamp=start.strftime('%Y-%m-%d %H:%M:%S') # <codecell> # set the magnitude of the polycollection to the speed collection.set_array(mag) collection.norm.vmin=0 collection.norm.vmax=0.5 # <codecell> fig = plt.figure(figsize=(12,12)) ax=fig.add_subplot(111) m.drawmapboundary(fill_color='0.3') #m.drawcoastlines() #m.fillcontinents() # add the speed as colored triangles ax.add_collection(collection) # add polygons to axes on basemap instance # add the vectors Q = m.quiver(xc,yc,u,v,scale=30) # add a key for the vectors
def shapes(shapes, data=None, colorbar=False, colorbar_ticklabels=None, norm=None, with_labels=False, edgecolors=None, facecolors=None, fontsize=None, ax=None, **kwds): """ Plot `data` on the basis of a dictionary of shapes. `data` must be given as a pandas Series with the corresponding keys of shapes as index. Parameters ---------- shapes : dict | pd.Series Dictionary of shapes data : pd.Series Float valued data to be plotted. If data is omitted, np.arange(N) will be used. with_labels : bool Whether to plot the name of each shape at its centroid Returns ------- collection : PolyCollection """ if 'outline' in kwds: # deprecated if kwds.pop('outline'): facecolors = 'none' if 'colour' in kwds: # deprecated edgecolors = kwds.pop('colour') if ax is None: ax = plt.gca() if not isinstance(shapes, pd.Series): shapes = pd.Series(shapes) def flatten_multipolygons(shapes): flat_shapes = [] flat_index = [] for n, sh in shapes.iteritems(): if isinstance(sh, MultiPolygon): flat_shapes += list(sh) flat_index += [n] * len(sh) else: flat_shapes.append(sh) flat_index.append(n) return pd.Series(flat_shapes, index=flat_index) if isinstance(edgecolors, pd.Series): shapes = shapes.reindex(edgecolors.index) flat_shapes = flatten_multipolygons(shapes) edgecolors = edgecolors.reindex(flat_shapes.index) elif isinstance(facecolors, pd.Series): shapes = shapes.reindex(facecolors.index) flat_shapes = flatten_multipolygons(shapes) facecolors = facecolors.reindex(flat_shapes.index) elif isinstance(data, pd.Series): shapes = shapes.reindex(data.index) flat_shapes = flatten_multipolygons(shapes) data = data.reindex(flat_shapes.index) else: flat_shapes = flatten_multipolygons(shapes) if facecolors is None: data = pd.Series(np.arange(len(shapes)), index=shapes.index).reindex(flat_shapes.index) coll = PolyCollection((np.asarray(x.exterior) for x in flat_shapes), transOffset=ax.transData, facecolors=facecolors, edgecolors=edgecolors, **kwds) if data is not None: coll.set_array(data) if norm is not None: coll.set_norm(norm) ax.add_collection(coll, autolim=True) if colorbar: kwargs = dict() if isinstance(colorbar, dict): kwargs.update(colorbar) ## FIXME : sounds like a bug to me, but hey if norm is not None: norm.autoscale(data) cbar = plt.colorbar(mappable=coll, **kwargs) if colorbar_ticklabels is not None: cbar.ax.set_yticklabels(colorbar_ticklabels) if with_labels: for k, v in iteritems(shapes.reindex(data.index)): x, y = np.asarray(v.centroid) plt.text(x, y, k, fontsize=fontsize, horizontalalignment='center', verticalalignment='center') ax.autoscale_view() return coll
def plot2dscales(self, verts, area2, scale2): fig = plt.figure(10) ax1 = fig.add_subplot(221) ax2 = fig.add_subplot(222) ax3 = fig.add_subplot(223) ax4 = fig.add_subplot(224) poly2d1 = PolyCollection(verts) poly2d1.set_array(np.array(area2) / max(area2)) poly2d2 = PolyCollection(verts) poly2d2.set_array(np.array(scale2) / max(scale2)) poly2d3 = PolyCollection(verts) poly2d3.set_array(np.array(self.total_scale) / max(self.total_scale)) poly2d4 = PolyCollection(verts) poly2d4.set_array(self.required_pe * np.array(self.total_scale) / max(self.total_scale)) lim = max(self.geom.pix_x).value ax1.add_collection(poly2d1) ax1.set_xlim(-lim, lim) ax1.set_ylim(-lim, lim) ax1.set_xlabel('X') ax1.set_ylabel('Y') ax1.set_title('Geometry Scale') ax2.add_collection(poly2d2) ax2.set_xlim(-lim, lim) ax2.set_ylim(-lim, lim) ax2.set_xlabel('X') ax2.set_ylabel('Y') ax2.set_title('Angular Pulse Scale') ax3.add_collection(poly2d3) ax3.set_xlim(-lim, lim) ax3.set_ylim(-lim, lim) ax3.set_xlabel('X') ax3.set_ylabel('Y') ax3.set_title('Total Scale') ax4.add_collection(poly2d4) ax4.set_xlim(-lim, lim) ax4.set_ylim(-lim, lim) ax4.set_xlabel('X') ax4.set_ylabel('Y') ax4.set_title('p.e. per pixel') fig.colorbar(poly2d1, ax=ax1) fig.colorbar(poly2d2, ax=ax2) fig.colorbar(poly2d3, ax=ax3) fig.colorbar(poly2d4, ax=ax4) fig20 = plt.figure(20) ax20 = fig20.add_subplot(111) dist = np.sqrt(self.geom.pix_x**2 + self.geom.pix_y**2) plt.scatter( dist, self.required_pe * np.array(self.total_scale) / max(self.total_scale)) # # print(dist) # # tmpout=open('tmp_true_pe_dist.txt', 'w') # arr = np.array(self.total_scale)/max(self.total_scale) # for i in range(len(dist)): # tmpout.write('%s\t%s\n' %(dist[i].value, arr[i])) # # print(self.required_pe * np.array(self.total_scale)/max(self.total_scale)) ax20.set_xlabel('distance') ax20.set_ylabel('number of p.e.')
def plot_mic_patches(self, plotType=1, minConfidence=0, maxConfidence=1, limitang=False, angles=[]): indx = [] for i in range(0, len(self.snp)): if self.snp[i, 9] >= minConfidence and self.snp[i, 9] <= maxConfidence: indx.append(i) if limitang: indx = self.angle_limiter(indx, self.snp, angles) else: indx = list(range(0, len(self.snp))) #indx=minConfidence<=self.snp[:,9]<=maxConfidence minsw = self.sw / float(2**self.snp[0, 4]) tsw1 = minsw * 0.5 tsw2 = -minsw * 0.5 * 3**0.5 ntri = len(self.snp) if plotType == 2: fig, ax = plt.subplots() if self.bpatches == False: xy = self.snp[:, :2] tmp = np.asarray([[tsw1] * ntri, (-1)**self.snp[:, 3] * tsw2]).transpose() tris = np.asarray([[[0, 0]] * ntri, [[minsw, 0]] * ntri, tmp]) self.patches = np.swapaxes(tris + xy, 0, 1) self.bpatches = True p = PolyCollection(self.patches[indx], cmap='viridis') p.set_array(self.color2[indx]) p.set_edgecolor('face') ax.add_collection(p) ax.set_xlim([-0.6, 0.6]) ax.set_ylim([-0.6, 0.6]) fig.colorbar(p, ax=ax) plt.show() if plotType == 1: fig, ax = plt.subplots() N = len(self.snp) mat = np.empty([N, 3, 3]) quat = np.empty([N, 4]) rod = np.empty([N, 3]) if self.bcolor1 == False: colors, maxangs, minangs = set_color_range( self, N, indx, mat, quat, rod) self.color1 = colors #print("Color: ", self.color1) #self.bcolor1=True if self.bpatches == False: xy = self.snp[:, :2] tmp = np.asarray([[tsw1] * ntri, (-1)**self.snp[:, 3] * tsw2]).transpose() tris = np.asarray([[[0, 0]] * ntri, [[minsw, 0]] * ntri, tmp]) self.patches = np.swapaxes(tris + xy, 0, 1) self.bpatches = True p = PolyCollection(self.patches[indx], cmap='viridis') p.set_color(self.color1[indx]) ax.add_collection(p) '''Yo future grayson, make sure interactive is a parameter!''' xmin = self.snp[indx[0], 0] xmax = self.snp[indx[0], 0] ymin = self.snp[indx[0], 1] ymax = self.snp[indx[0], 1] for i in indx: if self.snp[i, 0] <= xmin: xmin = self.snp[i, 0] if self.snp[i, 0] >= xmax: xmax = self.snp[i, 0] if self.snp[i, 1] <= ymin: ymin = self.snp[i, 1] if self.snp[i, 1] >= ymax: ymax = self.snp[i, 1] if abs(xmax - xmin) > abs(ymax - ymin): side_length = abs(xmax - xmin) else: side_length = abs(ymax - ymin) ax.set_xlim([xmin - .1, xmin + side_length + .1]) ax.set_ylim([ymin - .1, ymin + side_length + .1]) #note, previously, -.6<=x,y<=.6 voxels = VoxelClick(fig, self.snp, self.sw, self) voxels.connect() print("-------------------------------------------------") print("MaxRod (R,G,B): ", maxangs) print("MinRod (R,G,B): ", minangs) """write line here for adding text next to the plot""" """ maxs = ','.join(str(np.round_(x,decimals=4)) for x in maxangs) mins = ','.join(str(np.round_(x,decimals=4)) for x in minangs) plt.figtext(0.76, 0.5, "mins :"+maxs+"\nmaxes:"+mins) #plt.tight_layout() plt.gcf().subplots_adjust(right=0.75) #adjusting window for text to fit """ plt.show()
def __main__(request, actions, u, v, width, height, lonmax, lonmin, latmax, latmin, index, lon, lat, lonn, latn, nv): fig = Plot.figure(dpi=150, facecolor='none', edgecolor='none') fig.set_alpha(0) #ax = fig.add_subplot(111) projection = request.GET["projection"] m = Basemap( llcrnrlon=lonmin, llcrnrlat=latmin, urcrnrlon=lonmax, urcrnrlat=latmax, projection=projection, #lat_0 =(latmax + latmin) / 2, lon_0 =(lonmax + lonmin) / 2, lat_ts=0.0, ) #lonn, latn = m(lonn, latn) m.ax = fig.add_axes([0, 0, 1, 1]) #fig.set_figsize_inches((20/m.aspect, 20.)) fig.set_figheight(5) fig.set_figwidth(5 / m.aspect) if "regrid" in actions: #import fvcom_compute.fvcom_stovepipe.regrid as regrid #wid = numpy.max((width, height)) #size = (lonmax - lonmin) / wid #hi = (latmax - latmin) / size #hi = math.ceil(hi) #reglon = numpy.linspace(numpy.negative(lonmin), numpy.negative(lonmax), wid) #reglon = numpy.negative(reglon) #reglat = numpy.linspace(latmin, latmax, hi) #if "pcolor" in actions: # mag = numpy.power(u.__abs__(), 2)+numpy.power(v.__abs__(), 2) # mag = numpy.sqrt(mag) # newvalues = regrid.regrid(mag, lonn, latn, nv, reglon, reglat, size) # reglon, reglat = numpy.meshgrid(reglon, reglat) # grid = reorderArray(newvalues, len(reglat[:,1]), len(reglon[1,:])) # ax = fig.add_subplot(111) # ax.pcolor(reglon, reglat, grid) #if "contours" in actions: # mag = numpy.power(u.__abs__(), 2)+numpy.power(v.__abs__(), 2) # mag = numpy.sqrt(mag) # newvalues = regrid.regrid(mag, lonn, latn, nv, reglon, reglat, size) # reglon, reglat = numpy.meshgrid(reglon, reglat) # grid = reorderArray(newvalues, len(reglat[:,1]), len(reglon[1,:])) # ax = fig.add_subplot(111) # ax.contourf(reglon, reglat, grid) #if "vectors" in actions: # newv = regrid.regrid(v, lonn, latn, nv, reglon, reglat, size) # newu = regrid.regrid(u, lonn, latn, nv, reglon, reglat, size) # mag = numpy.power(newu.__abs__(), 2)+numpy.power(newv.__abs__(), 2) # mag = numpy.sqrt(mag) # ax = fig.add_subplot(111) # ax.quiver(reglon, reglat, newu, newv, mag, pivot='mid') pass else: if "vectors" in actions: mag = numpy.power(u.__abs__(), 2) + numpy.power(v.__abs__(), 2) mag = numpy.sqrt(mag) #ax = fig.add_subplot(111) #ax.quiver(lon, lat, u, v, mag, pivot='mid') lon, lat = m(lon, lat) m.quiver(lon, lat, u, v, mag, pivot='mid') ax = Plot.gca() elif "contours" in actions: mag = numpy.power(u.__abs__(), 2) + numpy.power(v.__abs__(), 2) mag = numpy.sqrt(mag) ax = fig.add_subplot(111) ax.tricontourf(lon, lat, mag) elif "facets" in actions: #projection = request.GET["projection"] #m = Basemap(llcrnrlon=lonmin, llcrnrlat=latmin, # urcrnrlon=lonmax, urcrnrlat=latmax, projection=projection, # lat_0 =(latmax + latmin) / 2, lon_0 =(lonmax + lonmin) / 2, # ) lonn, latn = m(lonn, latn) #m.ax = fig.add_axes([0, 0, 1, 1]) #fig.set_figheight(20) #fig.set_figwidth(20/m.aspect) #m.drawmeridians(numpy.arange(0,360,1), color='0.5',) tri = Tri.Triangulation(lonn, latn, triangles=nv) mag = numpy.power(u.__abs__(), 2) + numpy.power(v.__abs__(), 2) mag = numpy.sqrt(mag) #ax.tripcolor(lon, lat, mag, shading="") #collection = PolyCollection(numpy.asarray([(lonn[node1],latn[node1]),(lonn[node2],latn[node2]),(lonn[node3],latn[node3])])) verts = numpy.concatenate((tri.x[tri.triangles][...,numpy.newaxis],\ tri.y[tri.triangles][...,numpy.newaxis]), axis=2) collection = PolyCollection(verts) collection.set_array(mag) collection.set_edgecolor('none') ax = Plot.gca() #m.add_collection(collection) #ax = Plot.gca() #m2.ax.add_collection(collection) ax.add_collection(collection) lonmax, latmax = m(lonmax, latmax) lonmin, latmin = m(lonmin, latmin) ax.set_xlim(lonmin, lonmax) ax.set_ylim(latmin, latmax) ax.set_frame_on(False) ax.set_clip_on(False) ax.set_position([0, 0, 1, 1]) #Plot.yticks(visible=False) #Plot.xticks(visible=False) #Plot.axis('off') canvas = Plot.get_current_fig_manager().canvas response = HttpResponse(content_type='image/png') canvas.print_png(response) return response
def tripcolor(ax, *args, **kwargs): """ Create a pseudocolor plot of an unstructured triangular grid to the :class:`~matplotlib.axes.Axes`. The triangulation can be specified in one of two ways; either:: tripcolor(triangulation, ...) where triangulation is a :class:`~matplotlib.tri.Triangulation` object, or :: tripcolor(x, y, ...) tripcolor(x, y, triangles, ...) tripcolor(x, y, triangles=triangles, ...) tripcolor(x, y, mask=mask, ...) tripcolor(x, y, triangles, mask=mask, ...) in which case a Triangulation object will be created. See :class:`~matplotlib.tri.Triangulation` for a explanation of these possibilities. The next argument must be *C*, the array of color values, one per point in the triangulation. The colors used for each triangle are from the mean C of the triangle's three points. The remaining kwargs are the same as for :meth:`~matplotlib.axes.Axes.pcolor`. **Example:** .. plot:: mpl_examples/pylab_examples/tripcolor_demo.py """ if not ax._hold: ax.cla() alpha = kwargs.pop('alpha', 1.0) norm = kwargs.pop('norm', None) cmap = kwargs.pop('cmap', None) vmin = kwargs.pop('vmin', None) vmax = kwargs.pop('vmax', None) shading = kwargs.pop('shading', 'flat') tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args, **kwargs) x = tri.x y = tri.y triangles = tri.get_masked_triangles() # Vertices of triangles. verts = np.concatenate((x[triangles][...,np.newaxis], y[triangles][...,np.newaxis]), axis=2) C = np.asarray(args[0]) if C.shape != x.shape: raise ValueError('C array must have same length as triangulation x and' ' y arrays') # Color values, one per triangle, mean of the 3 vertex color values. C = C[triangles].mean(axis=1) if shading == 'faceted': edgecolors = (0,0,0,1), linewidths = (0.25,) else: edgecolors = 'face' linewidths = (1.0,) kwargs.setdefault('edgecolors', edgecolors) kwargs.setdefault('antialiaseds', (0,)) kwargs.setdefault('linewidths', linewidths) collection = PolyCollection(verts, **kwargs) collection.set_alpha(alpha) collection.set_array(C) if norm is not None: assert(isinstance(norm, Normalize)) 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_None() ax.grid(False) minx = tri.x.min() maxx = tri.x.max() miny = tri.y.min() maxy = tri.y.max() corners = (minx, miny), (maxx, maxy) ax.update_datalim( corners) ax.autoscale_view() ax.add_collection(collection) return collection
def tile(self, x, y, w, h, color=None, anchor='center', edgecolors='face', linewidth=0.8, **kwargs): """Plot rectanguler tiles based onto these `Axes`. ``x`` and ``y`` give the anchor point for each tile, with ``w`` and ``h`` giving the extent in the X and Y axis respectively. Parameters ---------- x, y, w, h : `array_like`, shape (n, ) Input data color : `array_like`, shape (n, ) Array of amplitudes for tile color anchor : `str`, optional Anchor point for tiles relative to ``(x, y)`` coordinates, one of - ``'center'`` - center tile on ``(x, y)`` - ``'ll'`` - ``(x, y)`` defines lower-left corner of tile - ``'lr'`` - ``(x, y)`` defines lower-right corner of tile - ``'ul'`` - ``(x, y)`` defines upper-left corner of tile - ``'ur'`` - ``(x, y)`` defines upper-right corner of tile **kwargs Other keywords are passed to :meth:`~matplotlib.collections.PolyCollection` Returns ------- collection : `~matplotlib.collections.PolyCollection` the collection of tiles drawn Examples -------- >>> import numpy >>> from matplotlib import pyplot >>> import gwpy.plot # to get gwpy's Axes >>> x = numpy.arange(10) >>> y = numpy.arange(x.size) >>> w = numpy.ones_like(x) * .8 >>> h = numpy.ones_like(x) * .8 >>> fig = pyplot.figure() >>> ax = fig.gca() >>> ax.tile(x, y, w, h, anchor='ll') >>> pyplot.show() """ # get color and sort if color is not None and kwargs.get('c_sort', True): sortidx = color.argsort() x = x[sortidx] y = y[sortidx] w = w[sortidx] h = h[sortidx] color = color[sortidx] # define how to make a polygon for each tile if anchor == 'll': def _poly(x, y, w, h): return ((x, y), (x, y+h), (x+w, y+h), (x+w, y)) elif anchor == 'lr': def _poly(x, y, w, h): return ((x-w, y), (x-w, y+h), (x, y+h), (x, y)) elif anchor == 'ul': def _poly(x, y, w, h): return ((x, y-h), (x, y), (x+w, y), (x+w, y-h)) elif anchor == 'ur': def _poly(x, y, w, h): return ((x-w, y-h), (x-w, y), (x, y), (x, y-h)) elif anchor == 'center': def _poly(x, y, w, h): return ((x-w/2., y-h/2.), (x-w/2., y+h/2.), (x+w/2., y+h/2.), (x+w/2., y-h/2.)) else: raise ValueError("Unrecognised tile anchor {!r}".format(anchor)) # build collection cmap = kwargs.pop('cmap', rcParams['image.cmap']) coll = PolyCollection((_poly(*tile) for tile in zip(x, y, w, h)), edgecolors=edgecolors, linewidth=linewidth, **kwargs) if color is not None: coll.set_array(color) coll.set_cmap(cmap) out = self.add_collection(coll) self.autoscale_view() return out
def overlayFan(myData,myMap,myFig,param,coords='geo',gsct=0,site=None,\ fov=None,gs_flg=[],fill=True,velscl=1000.,dist=1000., cmap=None,norm=None,alpha=1): """A function of overlay radar scan data on a map **Args**: * **myData (:class:`pydarn.sdio.radDataTypes.scanData` or :class:`pydarn.sdio.radDataTypes.beamData` or list of :class:`pydarn.sdio.radDataTypes.beamData` objects)**: a radar beam object, a radar scanData object, or simply a list of radar beams * **myMap**: the map we are plotting on * **[param]**: the parameter we are plotting * **[coords]**: the coordinates we are plotting in * **[param]**: the parameter to be plotted, valid inputs are 'velocity', 'power', 'width', 'elevation', 'phi0'. default = 'velocity * **[gsct]**: a flag indicating whether we are distinguishing ground scatter. default = 0 * **[intensities]**: a list of intensities (used for colorbar) * **[fov]**: a radar fov object * **[gs_flg]**: a list of gs flags, 1 per range gate * **[fill]**: a flag indicating whether to plot filled or point RB cells. default = True * **[velscl]**: the velocity to use as baseline for velocity vector length, only applicable if fill = 0. default = 1000 * **[lines]**: an array to have the endpoints of velocity vectors. only applicable if fill = 0. default = [] * **[dist]**: the length in map projection coords of a velscl length velocity vector. default = 1000. km **OUTPUTS**: NONE **EXAMPLE**: :: overlayFan(aBeam,myMap,param,coords,gsct=gsct,site=sites[i],fov=fovs[i],\ verts=verts,intensities=intensities,gs_flg=gs_flg) Written by AJ 20121004 """ if(site == None): site = pydarn.radar.site(radId=myData[0].stid, dt=myData[0].time) if(fov == None): fov = pydarn.radar.radFov.fov(site=site,rsep=myData[0].prm.rsep,\ ngates=myData[0].prm.nrang+1,nbeams= site.maxbeam,coords=coords) if(isinstance(myData,pydarn.sdio.beamData)): myData = [myData] gs_flg,lines = [],[] if fill: verts,intensities = [],[] else: verts,intensities = [[],[]],[[],[]] #loop through gates with scatter for myBeam in myData: for k in range(0,len(myBeam.fit.slist)): if myBeam.fit.slist[k] not in fov.gates: continue r = myBeam.fit.slist[k] if fill: x1,y1 = myMap(fov.lonFull[myBeam.bmnum,r],fov.latFull[myBeam.bmnum,r]) x2,y2 = myMap(fov.lonFull[myBeam.bmnum,r+1],fov.latFull[myBeam.bmnum,r+1]) x3,y3 = myMap(fov.lonFull[myBeam.bmnum+1,r+1],fov.latFull[myBeam.bmnum+1,r+1]) x4,y4 = myMap(fov.lonFull[myBeam.bmnum+1,r],fov.latFull[myBeam.bmnum+1,r]) #save the polygon vertices verts.append(((x1,y1),(x2,y2),(x3,y3),(x4,y4),(x1,y1))) #save the param to use as a color scale if(param == 'velocity'): intensities.append(myBeam.fit.v[k]) elif(param == 'power'): intensities.append(myBeam.fit.p_l[k]) elif(param == 'width'): intensities.append(myBeam.fit.w_l[k]) elif(param == 'elevation' and myBeam.prm.xcf): intensities.append(myBeam.fit.elv[k]) elif(param == 'phi0' and myBeam.prm.xcf): intensities.append(myBeam.fit.phi0[k]) else: x1,y1 = myMap(fov.lonCenter[myBeam.bmnum,r],fov.latCenter[myBeam.bmnum,r]) verts[0].append(x1) verts[1].append(y1) x2,y2 = myMap(fov.lonCenter[myBeam.bmnum,r+1],fov.latCenter[myBeam.bmnum,r+1]) theta = math.atan2(y2-y1,x2-x1) x2,y2 = x1+myBeam.fit.v[k]/velscl*(-1.0)*math.cos(theta)*dist,y1+myBeam.fit.v[k]/velscl*(-1.0)*math.sin(theta)*dist lines.append(((x1,y1),(x2,y2))) #save the param to use as a color scale if(param == 'velocity'): intensities[0].append(myBeam.fit.v[k]) elif(param == 'power'): intensities[0].append(myBeam.fit.p_l[k]) elif(param == 'width'): intensities[0].append(myBeam.fit.w_l[k]) elif(param == 'elevation' and myBeam.prm.xcf): intensities[0].append(myBeam.fit.elv[k]) elif(param == 'phi0' and myBeam.prm.xcf): intensities[0].append(myBeam.fit.phi0[k]) if(myBeam.fit.p_l[k] > 0): intensities[1].append(myBeam.fit.p_l[k]) else: intensities[1].append(0.) if(gsct): gs_flg.append(myBeam.fit.gflg[k]) #do the actual overlay if(fill): #if we have data if(verts != []): if(gsct == 0): inx = numpy.arange(len(verts)) else: inx = numpy.where(numpy.array(gs_flg)==0) x = PolyCollection(numpy.array(verts)[numpy.where(numpy.array(gs_flg)==1)], facecolors='.3',linewidths=0,zorder=5,alpha=alpha) myFig.gca().add_collection(x, autolim=True) pcoll = PolyCollection(numpy.array(verts)[inx], edgecolors='face',linewidths=0,closed=False,zorder=4, alpha=alpha,cmap=cmap,norm=norm) #set color array to intensities pcoll.set_array(numpy.array(intensities)[inx]) myFig.gca().add_collection(pcoll, autolim=True) return intensities,pcoll else: #if we have data if(verts != [[],[]]): if(gsct == 0): inx = numpy.arange(len(verts[0])) else: inx = numpy.where(numpy.array(gs_flg)==0) #plot the ground scatter as open circles x = myFig.scatter(numpy.array(verts[0])[numpy.where(numpy.array(gs_flg)==1)],\ numpy.array(verts[1])[numpy.where(numpy.array(gs_flg)==1)],\ s=.1*numpy.array(intensities[1])[numpy.where(numpy.array(gs_flg)==1)],\ zorder=5,marker='o',linewidths=.5,facecolors='w',edgecolors='k') myFig.gca().add_collection(x, autolim=True) #plot the i-s as filled circles ccoll = myFig.gca().scatter(numpy.array(verts[0])[inx],numpy.array(verts[1])[inx], \ s=.1*numpy.array(intensities[1])[inx],zorder=10,marker='o',linewidths=.5, \ edgecolors='face',cmap=cmap,norm=norm) #set color array to intensities ccoll.set_array(numpy.array(intensities[0])[inx]) myFig.gca().add_collection(ccoll) #plot the velocity vectors lcoll = LineCollection(numpy.array(lines)[inx],linewidths=.5,zorder=12,cmap=cmap,norm=norm) lcoll.set_array(numpy.array(intensities[0])[inx]) myFig.gca().add_collection(lcoll) return intensities,lcoll
def _gen2d3d(*args, **pltkwargs): # UPDATE """ Abstract layout for 2d plot. For convienence, a few special labels, colorbar and background keywords have been implemented. If these are not adequate, it one can add custom colorbars, linelabels background images etc... easily just by using respecitve calls to plot (plt.colorbar(), plt.imshow(), plt.clabel() ); my implementations are only for convienences and some predefined, cool styles. countours: Number of desired contours from output. label: Predefined label types. For now, only integer values 1,2. Use plt.clabel to add a custom label. background: Integers 1,2 will add gray or autumn colormap under contour plot. Use plt.imgshow() to generate custom background, or pass a PIL-opened image (note, proper image scaling not yet implemented). c_iso, r_iso: These control how man column and row iso lines will be projected onto the 3d plot. For example, if c_iso=10, then 10 isolines will be plotted as columns, despite the actual length of the columns. Alternatively, one can pass in c_stride directly, which is a column step size rather than an absolute number, and c_iso will be disregarded. fill: bool (False) Fill between contour lines. **pltkwargs: Will be passed directly to plt.contour(). Returns ------- tuple: (Axes, SurfaceFunction) Returns axes object and the surface function (e.g. contours for contour plot. Surface for surface plot. """ # Use a label mapper to allow for datetimes in any plot x/y axis _x_dti = _ = _y_dti = False # Passed Spectra if len(args) == 1: ts = args[0] try: index = np.array([dates.date2num(x) for x in ts.index]) _x_dti = True except AttributeError: index = ts.index.values #VALUES NECESSARY FOR POLY CMAP try: cols = np.array([dates.date2num(x) for x in ts.columns]) _y_dti = True except AttributeError: cols = ts.columns.values #VALUES NECESSARY FOR POLY CMAP yy, xx = np.meshgrid(cols, index) # Passed xx, yy, ts/zz elif len(args) == 3: xx, yy, ts = args cols, index = ts.columns.values, ts.index.values else: raise PlotError("Please pass a single spectra, or xx, yy, zz. Got %s args" % len(args)) # Boilerplate from basic_plots._genplot(); could refactor as decorator xlabel = pltkwargs.pop('xlabel', '') ylabel = pltkwargs.pop('ylabel', '') zlabel = pltkwargs.pop('zlabel', '') title = pltkwargs.pop('title', '') # Choose plot kind kind = pltkwargs.pop('kind', 'contour') grid = pltkwargs.pop('grid', '') # pltkwargs.setdefault('legend', False) #(any purpose in 2d?) # LEGEND FOR 2D PLOT: http://stackoverflow.com/questions/10490302/how-do-you-create-a-legend-for-a-contour-plot-in-matplotlib pltkwargs.setdefault('linewidth', 1) cbar = pltkwargs.pop('cbar', False) fig = pltkwargs.pop('fig', None) ax = pltkwargs.pop('ax', None) fill = pltkwargs.pop('fill', False) xlim = pltkwargs.pop('xlim', None) ylim = pltkwargs.pop('ylim', None) zlim = pltkwargs.pop('zlim', None) #Private attributes _modifyax = pltkwargs.pop('_modifyax', True) contours = pltkwargs.pop('contours', 6) label = pltkwargs.pop('label', None) projection = None if kind in PLOTPARSER.plots_3d: projection = '3d' elev = pltkwargs.pop('elev', 35) azim = pltkwargs.pop('azim', -135) view = pltkwargs.pop('view', None) if view: if view == 1: elev, azim = 35, -135 elif view == 2: elev, azim = 35, -45 elif view == 3: elev, azim = 20, -10 # Side view elif view == 4: elev, azim = 20, -170 elif view == 5: elev, azim = 0,-90 elif view == 6: elev, azim = 65, -90 else: raise PlotError('View must be between 1 and 6; otherwise set' ' "elev" and "azim" keywords.') # Orientation of zlabel (doesn't work...) _zlabel_rotation = 0.0 if azim < 0: _zlabel_rotation = 90.0 c_iso = pltkwargs.pop('c_iso', 10) r_iso = pltkwargs.pop('r_iso', 10) if c_iso > ts.shape[1] or c_iso < 0: raise PlotError('"c_iso" must be between 0 and %s, got "%s"' % (ts.shape[1], c_iso)) if r_iso > ts.shape[0] or r_iso < 0: raise PlotError('"r_iso" must be between 0 and %s, got "%s"' % (ts.shape[0], r_iso)) if c_iso == 0: cstride = 0 else: cstride = _ir(ts.shape[1]/float(c_iso) ) if r_iso == 0: rstride = 0 else: rstride = _ir(ts.shape[0]/float(r_iso) ) pltkwargs.setdefault('cstride', cstride) pltkwargs.setdefault('rstride', rstride) elif kind == 'contour': pass else: raise PlotError('_gen2d3d invalid kind: "%s". ' 'Choose from %s' % (kind, PLOTPARSER.plots_2d_3d)) # Is this the best logic for 2d/3d fig? if not ax: f = plt.figure() # ax = f.gca(projection=projection) ax = f.add_subplot(111, projection=projection) if not fig: fig = f labelsize = pltkwargs.pop('labelsize', 'medium') #Can also be ints titlesize = pltkwargs.pop('titlesize', 'large') ticksize = pltkwargs.pop('ticksize', '') #Put in default and remove bool gate # PLT.CONTOUR() doesn't take 'color'; rather, takes 'colors' for now if 'color' in pltkwargs: if kind == 'contour': pltkwargs['colors'] = pltkwargs.pop('color') # Convienence method to pass in string colors if 'colormap' in pltkwargs: pltkwargs['cmap'] = pltkwargs.pop('colormap') if 'cmap' in pltkwargs: if isinstance(pltkwargs['cmap'], basestring): pltkwargs['cmap'] = pu.cmget(pltkwargs['cmap']) # Contour Plots # ------------- # Broken background image ### More here http://matplotlib.org/examples/pylab_examples/image_demo3.html ### # Refactored with xx, yy instead of df.columns/index UNTESTED #if background: #xmin, xmax, ymin, ymax = xx.min(), xx.max(), yy.min(), yy.max() ## Could try rescaling contour rather than image: ##http://stackoverflow.com/questions/10850882/pyqt-matplotlib-plot-contour-data-on-top-of-picture-scaling-issue #if background==1: #im = ax.imshow(ts, interpolation='bilinear', origin='lower', #cmap=cm.gray, extent=(xmin, xmax, ymin, ymax)) #### This will take a custom image opened in PIL or it will take plt.imshow() returned from somewhere else #else: #try: #im = ax.imshow(background) #### Perhaps image was not correctly opened #except Exception: #raise badvalue_error(background, 'integer 1,2 or a PIL-opened image') # Note this overwrites the 'contours' variable from an int to array if kind == 'contour' or kind == 'contour3d': if fill: mappable = ax.contourf(xx, yy, ts, contours, **pltkwargs) #linewidths is a pltkwargs arg else: mappable = ax.contour(xx, yy, ts, contours, **pltkwargs) ### Pick a few label styles to choose from. if label: if label==1: ax.clabel(inline=1, fontsize=10) elif label==2: ax.clabel(levels[1::2], inline=1, fontsize=10) #label every second line else: raise PlotError(label, 'integer of value 1 or 2') elif kind == 'surf': mappable = ax.plot_surface(xx, yy, ts, **pltkwargs) # pltkwargs.pop('edgecolors') wires = overload_plot_wireframe(ax, xx, yy, ts, **pltkwargs) # print np.shape(wires._segments3d) wires = wire_cmap(wires, ax, cmap='jet') elif kind == 'wire': pltkwargs.setdefault('color', 'black') mappable = overload_plot_wireframe(ax, xx, yy, ts, **pltkwargs) elif kind == 'waterfall': edgecolors = pltkwargs.setdefault('edgecolors', None) pltkwargs.setdefault('closed', False) alpha = pltkwargs.setdefault('alpha', None) # Need to handle cmap/colors a bit differently for PolyCollection API if 'color' in pltkwargs: pltkwargs['facecolors']=pltkwargs.pop('color') cmap = pltkwargs.setdefault('cmap', None) if alpha is None: #as opposed to 0 alpha = 0.6 * (13.0/ts.shape[1]) if alpha > 0.6: alpha = 0.6 #Delete stride keywords for key in ['cstride', 'rstride']: try: del pltkwargs[key] except KeyError: pass # Verts are index dotted with data verts = [] for col in ts.columns: values = ts[col] values[0], values[-1] = values.min().min(), values.min().min() verts.append(list(zip(ts.index, values))) mappable = PolyCollection(verts, **pltkwargs) if cmap: mappable.set_array(cols) #If set array in __init__, autogens a cmap! mappable.set_cmap(pltkwargs['cmap']) mappable.set_alpha(alpha) #zdir is the direction used to plot; dont' fully understand ax.add_collection3d(mappable, zs=cols, zdir='x' ) # custom limits/labels polygon plot (reverse x,y) if not ylim: ylim = (max(index), min(index)) #REVERSE AXIS FOR VIEWING PURPOSES if not xlim: xlim = (min(cols), max(cols)) #x if not zlim: zlim = (min(ts.min()), max(ts.max())) #How to get absolute min/max of ts values # Reverse labels/DTI call for correct orientaion HACK HACK HACK xlabel, ylabel = ylabel, xlabel _x_dti, _y_dti = _y_dti, _x_dti azim = -1 * azim # General Features # ---------------- # Some applications (like add_projection) shouldn't alther axes features if not _modifyax: return (ax, mappable) if cbar: # Do I want colorbar outside of fig? Wouldn't be better on axes? try: fig.colorbar(mappable, ax=ax) except Exception: raise PlotError("Colorbar failed; did you pass a colormap?") if grid: ax.grid() # Format datetime axis # ------------------- if _x_dti: ax.xaxis.set_major_formatter(mplticker.FuncFormatter(format_date)) # Uncomment for custom 3d timestamp orientation # if projection: # for t1 in ax.yaxis.get_ticklabels(): # t1.set_ha('right') # t1.set_rotation(30) # ax.yaxis._axinfo['label']['space_factor'] = _TIMESTAMPPADDING if _y_dti: ax.yaxis.set_major_formatter(mplticker.FuncFormatter(format_date)) # Uncomment for custom 3d timestamp orientation # if projection: # for t1 in ax.yaxis.get_ticklabels(): # t1.set_ha('right') # t1.set_rotation(30) # ax.yaxis._axinfo['label']['space_factor'] = _TIMESTAMPPADDING if xlim: ax.set_xlim3d(xlim) if ylim: ax.set_ylim3d(ylim) if zlim: ax.set_zlim3d(zlim) # Set elevation/azimuth for 3d plots if projection: ax.view_init(elev, azim) ax.set_zlabel(zlabel, fontsize=labelsize, rotation= _zlabel_rotation) ax.set_xlabel(xlabel, fontsize=labelsize) ax.set_ylabel(ylabel, fontsize=labelsize) ax.set_title(title, fontsize=titlesize) # Return Ax, contours/surface/polygons etc... return (ax, mappable)
def plotCurrent(self, dtfrom, fnamebase): #self.figure.clf() #self.canvas.draw() #self.loadModel() self.progressBar.setValue(51) frmDate = self.dtFrom.dateTime() #print 'Plotting till date: ' + dtfrom.date().toString() # get velocity nearest to current time ##dtnow = dt.datetime.utcnow() + dt.timedelta(hours=0) day = dtfrom.date().day() month = dtfrom.date().month() year = dtfrom.date().year() hour = dtfrom.time().hour() minute = dtfrom.time().minute() second = dtfrom.time().second() msecond = dtfrom.time().msec() #print dir(dtnow) #print dtnow.time() startdt = dt.datetime(year, month, day, hour, minute, second, msecond) #print startdt #print start istart = netCDF4.date2index(startdt,self.time_var,select=self.interp_method) layer = 0 # surface layer u = self.nc.variables[self.uvar][istart, layer, :] v = self.nc.variables[self.vvar][istart, layer, :] mag = numpy.sqrt((u*u)+(v*v)) #print start #print istart self.progressBar.setValue(63) # Now try plotting speed and vectors with Basemap using a PolyCollection m = Basemap(projection='merc', llcrnrlat=self.lat.min(), urcrnrlat=self.lat.max(), llcrnrlon=self.lon.min(), urcrnrlon=self.lon.max(), lat_ts=self.lat.mean(), resolution=None) # project from lon,lat to mercator xnode, ynode = m(self.lon, self.lat) xc, yc = m(self.lonc, self.latc) nv = self.nc.variables[self.nvvar][:].T - 1 # create a TRI object with projected coordinates tri = Tri.Triangulation(xnode, ynode, triangles=nv) self.progressBar.setValue(77) sig_lay = self.nc.variables['siglay'] zeta = self.nc.variables['zeta'] # make a PolyCollection using triangles verts = concatenate((tri.x[tri.triangles][..., None], tri.y[tri.triangles][..., None]), axis=2) colorlut = [] fid = 0 for poly in verts: fid = fid + 1 collection = PolyCollection(verts) collection.set_edgecolor('none') self.progressBar.setValue(81) timestamp=startdt.strftime('%Y-%m-%d %H:%M:%S') # set the magnitude of the polycollection to the speed collection.set_array(mag) #sys.exit(1) collection.norm.vmin=0 collection.norm.vmax=0.5 #for path in collection.get_paths(): cmap =collection.cmap featurecount = fid redArray = matplotlib.colors.makeMappingArray(featurecount,cmap._segmentdata['red'], 1.0) greenArray = matplotlib.colors.makeMappingArray(featurecount,cmap._segmentdata['green'], 1.0) blueArray = matplotlib.colors.makeMappingArray(featurecount,cmap._segmentdata['blue'], 1.0) fid = 0 for path in collection.get_paths(): tricolor = self.makehexcolor(redArray[fid], greenArray[fid], blueArray[fid]) ##print tricolor name = "polygon#" + str(fid) colorlut.append(tricolor) #self.dbcur.execute("insert into polystyle values(?,?)",[name,str(tricolor) ]) fid = fid + 1 ds, lyr = self.init_vector(fnamebase) fid = 0 for poly in verts: #print "polygon" linecoords = [] feat = ogr.Feature( lyr.GetLayerDefn()) feat.SetField( "idd", "idd1" ) name = "polygon#" + str(fid) feat.SetField( "name", name ) feat.SetField( "color", colorlut[fid] ) fid = fid + 1 path = ogr.Geometry(ogr.wkbPolygon) extring = ogr.Geometry(ogr.wkbLinearRing) #path.getExteriorRing(); for coord in poly: ##print coord cc = m(coord[0],coord[1],inverse=True) #print cc x = cc[0] y = cc[1] pt = fid tstamp = startdt.strftime('%Y-%m-%d %H:%M:%S') z = 0 #z = sig_lay[pt:pt] * (zeta[pt:pt] - self.nc.variables[self.hvar][pt:pt]) #print (zeta[tstamp,pt]) # - self.nc.variables[self.hvar][pt]) #print zeta[:pt] #sys.exit(1) extring.AddPoint(x, y,z) extring.CloseRings() polygon = ogr.Geometry(ogr.wkbPolygon) polygon.AddGeometry(extring) feat.SetGeometry(polygon) if lyr.CreateFeature(feat) != 0: print "Failed to create feature in shapefile.\n" sys.exit( 1 ) ##else: ##print 'creaating feature' + str(feat.GetFID()); feat.Destroy() lyr.SyncToDisk() ax2=self.figure.add_subplot(111) coll = m.drawmapboundary(fill_color='0.3') self.progressBar.setValue(89) #m.drawcoastlines() #m.fillcontinents() # add the speed as colored triangles ax2.add_collection(collection) # add polygons to axes on basemap instance # add the vectors #Q = m.quiver(xc,yc,u,v,scale=30) Q = m.quiver(xc, yc, u, v, scale=100); ##self.progressBar.setValue(94) # add a key for the vectors qk = plt.quiverkey(Q,0.1,0.1,0.20,'0.2 m/s',labelpos='W') title('FVCOM Surface Current speed at %s UTC' % timestamp) # refresh canvas self.progressBar.setValue(97) self.canvas.draw() self.progressBar.setValue(100) self.animate(False) print "returning..." outfile = fnamebase + ".shp" return outfile
def __main__( request, actions, u, v, width, height, lonmax, lonmin, latmax, latmin, index, lon, lat, lonn, latn, nv): fig = Plot.figure(dpi=150, facecolor='none', edgecolor='none') fig.set_alpha(0) #ax = fig.add_subplot(111) projection = request.GET["projection"] m = Basemap(llcrnrlon=lonmin, llcrnrlat=latmin, urcrnrlon=lonmax, urcrnrlat=latmax, projection=projection, #lat_0 =(latmax + latmin) / 2, lon_0 =(lonmax + lonmin) / 2, lat_ts = 0.0, ) #lonn, latn = m(lonn, latn) m.ax = fig.add_axes([0, 0, 1, 1]) #fig.set_figsize_inches((20/m.aspect, 20.)) fig.set_figheight(5) fig.set_figwidth(5/m.aspect) if "regrid" in actions: #import fvcom_compute.fvcom_stovepipe.regrid as regrid #wid = numpy.max((width, height)) #size = (lonmax - lonmin) / wid #hi = (latmax - latmin) / size #hi = math.ceil(hi) #reglon = numpy.linspace(numpy.negative(lonmin), numpy.negative(lonmax), wid) #reglon = numpy.negative(reglon) #reglat = numpy.linspace(latmin, latmax, hi) #if "pcolor" in actions: # mag = numpy.power(u.__abs__(), 2)+numpy.power(v.__abs__(), 2) # mag = numpy.sqrt(mag) # newvalues = regrid.regrid(mag, lonn, latn, nv, reglon, reglat, size) # reglon, reglat = numpy.meshgrid(reglon, reglat) # grid = reorderArray(newvalues, len(reglat[:,1]), len(reglon[1,:])) # ax = fig.add_subplot(111) # ax.pcolor(reglon, reglat, grid) #if "contours" in actions: # mag = numpy.power(u.__abs__(), 2)+numpy.power(v.__abs__(), 2) # mag = numpy.sqrt(mag) # newvalues = regrid.regrid(mag, lonn, latn, nv, reglon, reglat, size) # reglon, reglat = numpy.meshgrid(reglon, reglat) # grid = reorderArray(newvalues, len(reglat[:,1]), len(reglon[1,:])) # ax = fig.add_subplot(111) # ax.contourf(reglon, reglat, grid) #if "vectors" in actions: # newv = regrid.regrid(v, lonn, latn, nv, reglon, reglat, size) # newu = regrid.regrid(u, lonn, latn, nv, reglon, reglat, size) # mag = numpy.power(newu.__abs__(), 2)+numpy.power(newv.__abs__(), 2) # mag = numpy.sqrt(mag) # ax = fig.add_subplot(111) # ax.quiver(reglon, reglat, newu, newv, mag, pivot='mid') pass else: if "vectors" in actions: mag = numpy.power(u.__abs__(), 2)+numpy.power(v.__abs__(), 2) mag = numpy.sqrt(mag) #ax = fig.add_subplot(111) #ax.quiver(lon, lat, u, v, mag, pivot='mid') lon, lat = m(lon, lat) m.quiver(lon, lat, u, v, mag, pivot='mid') ax = Plot.gca() elif "contours" in actions: mag = numpy.power(u.__abs__(), 2)+numpy.power(v.__abs__(), 2) mag = numpy.sqrt(mag) ax = fig.add_subplot(111) ax.tricontourf(lon, lat, mag) elif "facets" in actions: #projection = request.GET["projection"] #m = Basemap(llcrnrlon=lonmin, llcrnrlat=latmin, # urcrnrlon=lonmax, urcrnrlat=latmax, projection=projection, # lat_0 =(latmax + latmin) / 2, lon_0 =(lonmax + lonmin) / 2, # ) lonn, latn = m(lonn, latn) #m.ax = fig.add_axes([0, 0, 1, 1]) #fig.set_figheight(20) #fig.set_figwidth(20/m.aspect) #m.drawmeridians(numpy.arange(0,360,1), color='0.5',) tri = Tri.Triangulation(lonn,latn,triangles=nv) mag = numpy.power(u.__abs__(), 2)+numpy.power(v.__abs__(), 2) mag = numpy.sqrt(mag) #ax.tripcolor(lon, lat, mag, shading="") #collection = PolyCollection(numpy.asarray([(lonn[node1],latn[node1]),(lonn[node2],latn[node2]),(lonn[node3],latn[node3])])) verts = numpy.concatenate((tri.x[tri.triangles][...,numpy.newaxis],\ tri.y[tri.triangles][...,numpy.newaxis]), axis=2) collection = PolyCollection(verts) collection.set_array(mag) collection.set_edgecolor('none') ax = Plot.gca() #m.add_collection(collection) #ax = Plot.gca() #m2.ax.add_collection(collection) ax.add_collection(collection) lonmax, latmax = m(lonmax, latmax) lonmin, latmin = m(lonmin, latmin) ax.set_xlim(lonmin, lonmax) ax.set_ylim(latmin, latmax) ax.set_frame_on(False) ax.set_clip_on(False) ax.set_position([0,0,1,1]) #Plot.yticks(visible=False) #Plot.xticks(visible=False) #Plot.axis('off') canvas = Plot.get_current_fig_manager().canvas response = HttpResponse(content_type='image/png') canvas.print_png(response) return response
def draw_nx_tapered_edges(G, pos, edgelist=None, width=0.5, edge_color='k', style='solid', alpha=1.0, edge_cmap=None, edge_vmin=None, edge_vmax=None, ax=None, label=None, highlight=None, tapered=False, **kwds): """Draw the edges of the graph G. This draws only the edges of the graph G. Parameters ---------- G : graph A networkx graph pos : dictionary A dictionary with nodes as keys and positions as values. Positions should be sequences of length 2. edgelist : collection of edge tuples Draw only specified edges(default=G.edges()) width : float, or array of floats Line width of edges (default=1.0) edge_color : color string, or array of floats Edge color. Can be a single color format string (default='r'), or a sequence of colors with the same length as edgelist. If numeric values are specified they will be mapped to colors using the edge_cmap and edge_vmin,edge_vmax parameters. style : string Edge line style (default='solid') (solid|dashed|dotted,dashdot) alpha : float The edge transparency (default=1.0) edge_ cmap : Matplotlib colormap Colormap for mapping intensities of edges (default=None) edge_vmin,edge_vmax : floats Minimum and maximum for edge colormap scaling (default=None) ax : Matplotlib Axes object, optional Draw the graph in the specified Matplotlib axes. label : [None| string] Label for legend Returns ------- matplotlib.collection.LineCollection `LineCollection` of the edges Examples -------- >>> G=nx.dodecahedral_graph() >>> edges=nx.draw_networkx_edges(G,pos=nx.spring_layout(G)) Also see the NetworkX drawing examples at http://networkx.github.io/documentation/latest/gallery.html See Also -------- draw() draw_networkx() draw_networkx_nodes() draw_networkx_labels() draw_networkx_edge_labels() """ if ax is None: ax = plt.gca() if edgelist is None: edgelist = list(G.edges()) if not edgelist or len(edgelist) == 0: # no edges! return None if highlight is not None and (isinstance(edge_color, basestring) or not cb.iterable(edge_color)): idMap = {} nodes = G.nodes() for i in range(len(nodes)): idMap[nodes[i]] = i ecol = [edge_color] * len(edgelist) eHighlight = [ highlight[idMap[edge[0]]] or highlight[idMap[edge[1]]] for edge in edgelist ] for i in range(len(eHighlight)): if eHighlight[i]: ecol[i] = '0.0' edge_color = ecol # set edge positions if not cb.iterable(width): lw = np.full(len(edgelist), width) else: lw = width edge_pos = [] wdScale = 0.01 for i in range(len(edgelist)): e = edgelist[i] w = wdScale * lw[i] / 2 p0 = pos[e[0]] p1 = pos[e[1]] dx = p1[0] - p0[0] dy = p1[1] - p0[1] l = math.sqrt(dx * dx + dy * dy) edge_pos.append( ((p0[0] + w * dy / l, p0[1] - w * dx / l), (p0[0] - w * dy / l, p0[1] + w * dx / l), (p1[0], p1[1]))) edge_vertices = np.asarray(edge_pos) if not isinstance(edge_color, basestring) \ and cb.iterable(edge_color) \ and len(edge_color) == len(edge_vertices): if np.alltrue([isinstance(c, basestring) for c in edge_color]): # (should check ALL elements) # list of color letters such as ['k','r','k',...] edge_colors = tuple( [colorConverter.to_rgba(c, alpha) for c in edge_color]) elif np.alltrue([not isinstance(c, basestring) for c in edge_color]): # If color specs are given as (rgb) or (rgba) tuples, we're OK if np.alltrue( [cb.iterable(c) and len(c) in (3, 4) for c in edge_color]): edge_colors = tuple(edge_color) else: # numbers (which are going to be mapped with a colormap) edge_colors = None else: raise ValueError( 'edge_color must consist of either color names or numbers') else: if isinstance(edge_color, basestring) or len(edge_color) == 1: edge_colors = (colorConverter.to_rgba(edge_color, alpha), ) else: raise ValueError( 'edge_color must be a single color or list of exactly m colors where m is the number or edges' ) if tapered: edge_collection = PolyCollection( edge_vertices, facecolors=edge_colors, linewidths=0, antialiaseds=(1, ), transOffset=ax.transData, ) else: edge_collection = LineCollection( edge_pos, colors=edge_colors, linewidths=lw, antialiaseds=(1, ), linestyle=style, transOffset=ax.transData, ) edge_collection.set_zorder(1) # edges go behind nodes edge_collection.set_label(label) ax.add_collection(edge_collection) # Note: there was a bug in mpl regarding the handling of alpha values for # each line in a LineCollection. It was fixed in matplotlib in r7184 and # r7189 (June 6 2009). We should then not set the alpha value globally, # since the user can instead provide per-edge alphas now. Only set it # globally if provided as a scalar. if cb.is_numlike(alpha): edge_collection.set_alpha(alpha) if edge_colors is None: if edge_cmap is not None: assert (isinstance(edge_cmap, Colormap)) edge_collection.set_array(np.asarray(edge_color)) edge_collection.set_cmap(edge_cmap) if edge_vmin is not None or edge_vmax is not None: edge_collection.set_clim(edge_vmin, edge_vmax) else: edge_collection.autoscale() # update view minx = np.amin(np.ravel(edge_vertices[:, :, 0])) maxx = np.amax(np.ravel(edge_vertices[:, :, 0])) miny = np.amin(np.ravel(edge_vertices[:, :, 1])) maxy = np.amax(np.ravel(edge_vertices[:, :, 1])) w = maxx - minx h = maxy - miny padx, pady = 0.05 * w, 0.05 * h corners = (minx - padx, miny - pady), (maxx + padx, maxy + pady) ax.update_datalim(corners) ax.autoscale_view() return edge_collection
def overlayFan(myData, myMap, myFig, param, coords='geo', gsct=0, site=None, fov=None, gs_flg=[], fill=True, velscl=1000., dist=1000., cmap=None, norm=None, alpha=1): """A function of overlay radar scan data on a map Parameters ---------- myData : pydarn.sdio.radDataTypes.scanData or pydarn.sdio.radDataTypes.beamData or list of pydarn.sdio.radDataTypes.beamData objects A radar beam object, a radar scanData object, or simply a list of radar beams myMap : The map we are plotting on myFig : Figure object that we are plotting to coords : Optional[str] The coordinates we are plotting in. Default: geo param : Optional[str] The parameter to be plotted, valid inputs are 'velocity', 'power', 'width', 'elevation', 'phi0'. default = 'velocity gsct : Optional[boolean] A flag indicating whether we are distinguishing ground scatter. default = 0 intensities : Optional[ ] A list of intensities (used for colorbar) fov : Optional[pydarn.radar.radFov.fov] A radar fov object gs_flg : Optional[ ] A list of gs flags, 1 per range gate fill : Optional[boolean] A flag indicating whether to plot filled or point RB cells. default = True velscl : Optional[float] The velocity to use as baseline for velocity vector length, only applicable if fill = 0. default = 1000 lines : Optional[ ] An array to have the endpoints of velocity vectors. only applicable if fill = 0. default = [] dist : Optional [float] The length in map projection coords of a velscl length velocity vector. default = 1000. km Returns ------- intensities pcoll lcoll Example ------- overlayFan(aBeam,myMap,param,coords,gsct=gsct,site=sites[i],fov=fovs[i], verts=verts,intensities=intensities,gs_flg=gs_flg) """ from davitpy import pydarn if(isinstance(myData, pydarn.sdio.beamData)): myData = [myData] if(site is None): site = pydarn.radar.site(radId=myData[0].stid, dt=myData[0].time) if(fov is None): fov = pydarn.radar.radFov.fov(site=site, rsep=myData[0].prm.rsep, ngates=myData[0].prm.nrang + 1, nbeams=site.maxbeam, coords=coords, date_time=myData[0].time) gs_flg, lines = [], [] if fill: verts, intensities = [], [] else: verts, intensities = [[], []], [[], []] # loop through gates with scatter for myBeam in myData: for k in range(0, len(myBeam.fit.slist)): if myBeam.fit.slist[k] not in fov.gates: continue r = myBeam.fit.slist[k] if fill: x1, y1 = myMap(fov.lonFull[myBeam.bmnum, r], fov.latFull[myBeam.bmnum, r]) x2, y2 = myMap(fov.lonFull[myBeam.bmnum, r + 1], fov.latFull[myBeam.bmnum, r + 1]) x3, y3 = myMap(fov.lonFull[myBeam.bmnum + 1, r + 1], fov.latFull[myBeam.bmnum + 1, r + 1]) x4, y4 = myMap(fov.lonFull[myBeam.bmnum + 1, r], fov.latFull[myBeam.bmnum + 1, r]) # save the polygon vertices verts.append(((x1, y1), (x2, y2), (x3, y3), (x4, y4), (x1, y1))) # save the param to use as a color scale if(param == 'velocity'): intensities.append(myBeam.fit.v[k]) elif(param == 'power'): intensities.append(myBeam.fit.p_l[k]) elif(param == 'width'): intensities.append(myBeam.fit.w_l[k]) elif(param == 'elevation' and myBeam.prm.xcf): intensities.append(myBeam.fit.elv[k]) elif(param == 'phi0' and myBeam.prm.xcf): intensities.append(myBeam.fit.phi0[k]) else: x1, y1 = myMap(fov.lonCenter[myBeam.bmnum, r], fov.latCenter[myBeam.bmnum, r]) verts[0].append(x1) verts[1].append(y1) x2, y2 = myMap(fov.lonCenter[myBeam.bmnum, r + 1], fov.latCenter[myBeam.bmnum, r + 1]) theta = math.atan2(y2 - y1, x2 - x1) x2, y2 = x1 + myBeam.fit.v[k] / velscl * (-1.0) * \ math.cos(theta) * dist, y1 + myBeam.fit.v[k] / velscl * \ (-1.0) * math.sin(theta) * dist lines.append(((x1, y1), (x2, y2))) # save the param to use as a color scale if(param == 'velocity'): intensities[0].append(myBeam.fit.v[k]) elif(param == 'power'): intensities[0].append(myBeam.fit.p_l[k]) elif(param == 'width'): intensities[0].append(myBeam.fit.w_l[k]) elif(param == 'elevation' and myBeam.prm.xcf): intensities[0].append(myBeam.fit.elv[k]) elif(param == 'phi0' and myBeam.prm.xcf): intensities[0].append(myBeam.fit.phi0[k]) if(myBeam.fit.p_l[k] > 0): intensities[1].append(myBeam.fit.p_l[k]) else: intensities[1].append(0.) if(gsct): gs_flg.append(myBeam.fit.gflg[k]) # do the actual overlay if(fill): # if we have data if(verts != []): if(gsct == 0): inx = numpy.arange(len(verts)) else: inx = numpy.where(numpy.array(gs_flg) == 0) x = PolyCollection(numpy.array(verts)[numpy.where( numpy.array(gs_flg) == 1)], facecolors='.3', linewidths=0, zorder=5, alpha=alpha) myFig.gca().add_collection(x, autolim=True) pcoll = PolyCollection(numpy.array(verts)[inx], edgecolors='face', linewidths=0, closed=False, zorder=4, alpha=alpha, cmap=cmap, norm=norm) # set color array to intensities pcoll.set_array(numpy.array(intensities)[inx]) myFig.gca().add_collection(pcoll, autolim=True) return intensities, pcoll else: # if we have data if(verts != [[], []]): if(gsct == 0): inx = numpy.arange(len(verts[0])) else: inx = numpy.where(numpy.array(gs_flg) == 0) # plot the ground scatter as open circles x = myFig.scatter(numpy.array(verts[0])[numpy.where( numpy.array(gs_flg) == 1)], numpy.array(verts[1])[numpy.where( numpy.array(gs_flg) == 1)], s=.1 * numpy.array(intensities[1])[ numpy.where(numpy.array(gs_flg) == 1)], zorder=5, marker='o', linewidths=.5, facecolors='w', edgecolors='k') myFig.gca().add_collection(x, autolim=True) # plot the i-s as filled circles ccoll = myFig.gca().scatter(numpy.array(verts[0])[inx], numpy.array(verts[1])[inx], s=.1 * numpy.array( intensities[1])[inx], zorder=10, marker='o', linewidths=.5, edgecolors='face', cmap=cmap, norm=norm) # set color array to intensities ccoll.set_array(numpy.array(intensities[0])[inx]) myFig.gca().add_collection(ccoll) # plot the velocity vectors lcoll = LineCollection(numpy.array(lines)[inx], linewidths=.5, zorder=12, cmap=cmap, norm=norm) lcoll.set_array(numpy.array(intensities[0])[inx]) myFig.gca().add_collection(lcoll) return intensities, lcoll
def tripcolor(ax, *args, **kwargs): """ Create a pseudocolor plot of an unstructured triangular grid to the :class:`~matplotlib.axes.Axes`. The triangulation can be specified in one of two ways; either:: tripcolor(triangulation, ...) where triangulation is a :class:`~matplotlib.tri.Triangulation` object, or :: tripcolor(x, y, ...) tripcolor(x, y, triangles, ...) tripcolor(x, y, triangles=triangles, ...) tripcolor(x, y, mask, ...) tripcolor(x, y, mask=mask, ...) tripcolor(x, y, triangles, mask, ...) tripcolor(x, y, triangles, mask=mask, ...) in which case a Triangulation object will be created. See :class:`~matplotlib.tri.Triangulation` for a explanation of these possibilities. The next argument must be *C*, the array of color values, one per point in the triangulation. The colors used for each triangle are from the mean C of the triangle's three points. The remaining kwargs are the same as for :meth:`~matplotlib.axes.Axes.pcolor`. **Example:** .. plot:: mpl_examples/pylab_examples/tripcolor_demo.py """ if not ax._hold: ax.cla() alpha = kwargs.pop('alpha', 1.0) norm = kwargs.pop('norm', None) cmap = kwargs.pop('cmap', None) vmin = kwargs.pop('vmin', None) vmax = kwargs.pop('vmax', None) shading = kwargs.pop('shading', 'flat') tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args, **kwargs) x = tri.x y = tri.y triangles = tri.get_masked_triangles() # Vertices of triangles. verts = np.concatenate( (x[triangles][..., np.newaxis], y[triangles][..., np.newaxis]), axis=2) C = np.asarray(args[0]) if C.shape != x.shape: raise ValueError('C array must have same length as triangulation x and' ' y arrays') # Color values, one per triangle, mean of the 3 vertex color values. C = C[triangles].mean(axis=1) if shading == 'faceted': edgecolors = (0, 0, 0, 1), linewidths = (0.25, ) else: edgecolors = 'face' linewidths = (1.0, ) kwargs.setdefault('edgecolors', edgecolors) kwargs.setdefault('antialiaseds', (0, )) kwargs.setdefault('linewidths', linewidths) collection = PolyCollection(verts, **kwargs) collection.set_alpha(alpha) collection.set_array(C) if norm is not None: assert (isinstance(norm, Normalize)) 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_None() ax.grid(False) minx = tri.x.min() maxx = tri.x.max() miny = tri.y.min() maxy = tri.y.max() corners = (minx, miny), (maxx, maxy) ax.update_datalim(corners) ax.autoscale_view() ax.add_collection(collection) return collection
t = ncv['time'][:] y = ncv['node_y'][:] x = ncv['node_x'][:] s = ncv['hzg_ecosmo_sed2'][:] nv = ncv['nv'][:, :3] - 1 verts = [] for nvi in nv: verts.append([(x[i], y[i]) for i in nvi]) verts = asarray(verts) f = figure(figsize=(15, 5)) p = PolyCollection(verts, closed=True, edgecolor='none') p.set_array(s[0]) p.set_cmap(cm.RdYlBu_r) pn = PolyCollection(verts, closed=True, edgecolor='none') pn.set_array(arange(len(s[0]))) pn.set_cmap(cm.RdYlBu_r) ax = axes([0.1, 0.75, 0.88, 0.2]) ax.add_collection(p, autolim=True) autoscale() colorbar(p) ax = axes([0.1, 0.25, 0.88, 0.2]) ax.add_collection(pn, autolim=True) autoscale() colorbar(pn)
for i in range(clippedData.GetNumberOfCells()): cell = clippedData.GetCell(i) nPoints = cell.GetNumberOfPoints() points = np.zeros((nPoints, 2)) for pointI in range(nPoints): points[pointI, :] = cell.GetPoints().GetPoint(pointI)[:2] points[pointI, :] /= [scaleX, scaleY] polys.append(points) polyCollection = PolyCollection(polys, **kwargs) if "edgecolor" not in kwargs: polyCollection.set_edgecolor("face") data = np.copy(vtk_to_numpy(clippedData.GetCellData()['temp'])) polyCollection.set_array(data) ax = plt.gca() ax.add_collection(polyCollection) if colorbar: add_colorbar(polyCollection) if plotBoundaries: plot_boundaries(case, scaleX=scaleX, scaleY=scaleY) ax.set_xlim(xlim / scaleX) ax.set_ylim(ylim / scaleY) ax.set_aspect('equal') case.__delitem__('temp')
def plot_mic_patches(self, plotType, minConfidence, maxConfidence, indices): indx = [] for i in range(0, len(self.snp)): if self.snp[i, 9] >= minConfidence and self.snp[ i, 9] <= maxConfidence and i in indices: indx.append(i) #indx=minConfidence<=self.snp[:,9]<=maxConfidence minsw = self.sw / float(2**self.snp[0, 4]) tsw1 = minsw * 0.5 tsw2 = -minsw * 0.5 * 3**0.5 ntri = len(self.snp) if plotType == 2: fig, ax = plt.subplots() if self.bpatches == False: xy = self.snp[:, :2] tmp = np.asarray([[tsw1] * ntri, (-1)**self.snp[:, 3] * tsw2]).transpose() tris = np.asarray([[[0, 0]] * ntri, [[minsw, 0]] * ntri, tmp]) self.patches = np.swapaxes(tris + xy, 0, 1) self.bpatches = True p = PolyCollection(self.patches[indx], cmap='viridis') p.set_array(self.color2[indx]) p.set_edgecolor('face') ax.add_collection(p) ax.set_xlim([-0.6, 0.6]) ax.set_ylim([-0.6, 0.6]) fig.colorbar(p, ax=ax) plt.show() if plotType == 1: fig, ax = plt.subplots() N = len(self.snp) mat = np.empty([N, 3, 3]) quat = np.empty([N, 4]) rod = np.empty([N, 3]) if self.bcolor1 == False: maxr = 0.0 minr = 0.0 maxg = 0.0 ming = 0.0 maxb = 0.0 minb = 0.0 for i in range(N): if i in indx: mat[i, :, :] = RotRep.EulerZXZ2Mat(self.snp[i, 6:9] / 180.0 * np.pi) quat[i, :] = RotRep.quaternion_from_matrix( mat[i, :, :]) rod[i, :] = RotRep.rod_from_quaternion(quat[i, :]) if i == indx[0]: maxr = rod[i, 0] minr = rod[i, 0] maxg = rod[i, 1] ming = rod[i, 1] maxb = rod[i, 2] minb = rod[i, 2] else: if rod[i, 0] > maxr: maxr = rod[i, 0] elif rod[i, 0] < minr: minr = rod[i, 0] if rod[i, 1] > maxg: maxg = rod[i, 1] elif rod[i, 1] < ming: ming = rod[i, 1] if rod[i, 2] > maxb: maxb = rod[i, 2] elif rod[i, 2] < minb: minb = rod[i, 2] else: rod[i, :] = [0.0, 0.0, 0.0] print "Current rod values: ", rod maxrgb = [maxr, maxg, maxb] minrgb = [minr, ming, minb] colors = rod for j in range(N): for k in range(0, 3): colors[j, k] = (rod[j, k] - minrgb[k]) / (maxrgb[k] - minrgb[k]) self.color1 = colors print "Color: ", self.color1 #self.bcolor1=True if self.bpatches == False: xy = self.snp[:, :2] tmp = np.asarray([[tsw1] * ntri, (-1)**self.snp[:, 3] * tsw2]).transpose() tris = np.asarray([[[0, 0]] * ntri, [[minsw, 0]] * ntri, tmp]) self.patches = np.swapaxes(tris + xy, 0, 1) self.bpatches = True p = PolyCollection(self.patches[indx], cmap='viridis') p.set_color(self.color1[indx]) ax.add_collection(p) ax.set_xlim([-0.6, 0.6]) ax.set_ylim([-0.6, 0.6]) plt.show()
units=var_atts[varname]['units'] data=utils.get_packed_data(dt, tsvert, dtc) data=numpy.ma.masked_equal(data,fill_val,copy=False) # apply the scale_factor if scale_factor is not None: data=data.astype(scale_factor.dtype.char)*scale_factor # apply the add_offset if add_offset is not None: data+=add_offset qvert_list=mesh.getEntAdj(quads,iBase.Type.vertex) poly_list=[] for qv in qvert_list: cds=mesh.getVtxCoords(qv) poly_list.append(cds[:,[0,1]].tolist()) pcoll=PolyCollection(poly_list, edgecolor='none') pcoll.set_array(data) pcoll.set_cmap(cm.jet) a=fig.add_subplot(ncol,nrow,i) a.add_collection(pcoll, autolim=True) a.autoscale_view() colorbar(pcoll,orientation='vertical') title("%s (%s)" % (varname,units)) i+=1 show(0)
def overlay_raw_data(self, param="velocity", gsct=0, fill=True, velscl=1000., vel_lim=[-1000, 1000], srange_lim=[450, 4000], zorder=4, alpha=1, cmap=None, norm=None): """Overlays raw LOS data from radars""" from davitpy import pydarn import numpy as np import math from matplotlib.collections import PolyCollection, LineCollection losvel_mappable = None for i in range(len(self.data)): if self.data[i] is None: continue fov = self.fovs[i] site = self.sites[i] myData = self.data[i] gs_flg, lines = [], [] if fill: verts, intensities = [], [] else: verts = [[], []] intensities = [] #loop through gates with scatter for myBeam in myData: for k in range(len(myBeam.fit.slist)): if myBeam.fit.slist[k] not in fov.gates: continue if (myBeam.fit.slist[k] * myBeam.prm.rsep < srange_lim[0]) or\ (myBeam.fit.slist[k] * myBeam.prm.rsep > srange_lim[1]): continue # if (myBeam.fit.v[k] < vel_lim[0]) or\ # (myBeam.fit.v[k] > vel_lim[1]): # continue r = myBeam.fit.slist[k] if fill: x1, y1 = self.map_obj(fov.lonFull[myBeam.bmnum, r], fov.latFull[myBeam.bmnum, r]) x2, y2 = self.map_obj(fov.lonFull[myBeam.bmnum, r + 1], fov.latFull[myBeam.bmnum, r + 1]) x3, y3 = self.map_obj( fov.lonFull[myBeam.bmnum + 1, r + 1], fov.latFull[myBeam.bmnum + 1, r + 1]) x4, y4 = self.map_obj(fov.lonFull[myBeam.bmnum + 1, r], fov.latFull[myBeam.bmnum + 1, r]) # save the polygon vertices verts.append( ((x1, y1), (x2, y2), (x3, y3), (x4, y4), (x1, y1))) else: x1, y1 = self.map_obj(fov.lonCenter[myBeam.bmnum, r], fov.latCenter[myBeam.bmnum, r]) verts[0].append(x1) verts[1].append(y1) x2, y2 = self.map_obj( fov.lonCenter[myBeam.bmnum, r + 1], fov.latCenter[myBeam.bmnum, r + 1]) theta = math.atan2(y2 - y1, x2 - x1) x2 = x1 + myBeam.fit.v[k] * velscl * ( -1.0) * math.cos(theta) y2 = y1 + myBeam.fit.v[k] * velscl * ( -1.0) * math.sin(theta) lines.append(((x1, y1), (x2, y2))) if (gsct): gs_flg.append(myBeam.fit.gflg[k]) #save the param to use as a color scale if (param == 'velocity'): intensities.append(myBeam.fit.v[k]) #do the actual overlay if fill: #if we have data if (verts != []): if (gsct == 0): inx = np.arange(len(verts)) else: inx = np.where(np.array(gs_flg) == 0) # x = PolyCollection(np.array(verts)[np.where(np.array(gs_flg)==1)], # facecolors='.3',linewidths=0, # zorder=zorder+1,alpha=alpha) # self.map_obj.ax.add_collection(x, autolim=True) coll = PolyCollection(np.array(verts)[inx], edgecolors='face', linewidths=0, closed=False, zorder=zorder, alpha=alpha, cmap=cmap, norm=norm) #set color array to intensities coll.set_array(np.array(intensities)[inx]) self.map_obj.ax.add_collection(coll, autolim=True) else: #if we have data if (verts != [[], []]): if (gsct == 0): inx = np.arange(len(verts[0])) else: inx = np.where(np.array(gs_flg) == 0) #plot the ground scatter as open circles x = self.map_obj.ax.scatter(\ np.array(verts[0])[np.where(np.array(gs_flg)==1)], np.array(verts[1])[np.where(np.array(gs_flg)==1)], s=1.0, zorder=zorder,marker='o',linewidths=.5, facecolors='w',edgecolors='k') self.map_obj.ax.add_collection(x, autolim=True) # plot the i-s as filled circles ccoll = self.map_obj.ax.scatter( np.array(verts[0])[inx], np.array(verts[1])[inx], s=1.0, zorder=zorder + 1, marker='o', c=np.array(intensities)[inx], linewidths=.5, edgecolors='face', cmap=cmap, norm=norm) #set color array to intensities self.map_obj.ax.add_collection(ccoll) #plot the velocity vectors coll = LineCollection(np.array(lines)[inx], linewidths=.5, zorder=zorder + 2, cmap=cmap, norm=norm) coll.set_array(np.array(intensities)[inx]) self.map_obj.ax.add_collection(coll) if coll: losvel_mappable = coll self.losvel_mappable = losvel_mappable return
def __init__(self,dataObject, dataSet = 'active', beams = [4,7,13], coords = 'gate', xlim = None, ylim = None, axis = None, scale = None, plotZeros = False, xBoundaryLimits = None, yBoundaryLimits = None, yticks = None, ytick_lat_format = '.0f', autoScale = False, plotTerminator = True, axvlines = None, axvline_color = '0.25', secondary_coords = 'lat', plot_info = True, info_height_percent = 0.10, plot_title = True, cmap_handling = 'superdarn', plot_cbar = True, cbar_ticks = None, cbar_shrink = 1.0, cbar_fraction = 0.15, cbar_gstext_offset = -0.075, cbar_gstext_fontsize = None, model_text_size = 'small', y_labelpad = None, **kwArgs): from scipy import stats from davitpy.pydarn.plotting.rti import plotFreq,plotNoise # Calculate position information from plots. ################################### # Use a provided axis (or figure) to get the bounding box dimensions for the plots. # Then calculate where the RTI plots are actually going to go, and allow room for the # information plots. if axis == None: from matplotlib import pyplot as plt fig = plt.figure(figsize=figsize) axis = fig.add_subplot(111) pos = list(axis.get_position().bounds) fig = axis.get_figure() fig.delaxes(axis) nx_plots = 0 beams = np.array(beams) ny_plots = beams.size rti_width = pos[2] if plot_cbar: cbar_width = cbar_fraction * rti_width rti_width -= cbar_width rti_height_total = pos[3] if plot_info: info_height = info_height_percent * rti_height_total rti_height_total -= info_height rti_height = rti_height_total / float(ny_plots) # fig.add_axes(left,bottom,width,height) #Make some variables easier to get to... currentData = getDataSet(dataObject,dataSet) metadata = currentData.metadata latFull = currentData.fov.latFull lonFull = currentData.fov.lonFull latCenter = currentData.fov.latCenter lonCenter = currentData.fov.lonCenter time = currentData.time nrTimes, nrBeams, nrGates = np.shape(currentData.data) plot_nr = 0 xpos = pos[0] ypos = pos[1] if beams.size == 1: beams = [beams.tolist()] for beam in beams: plot_nr +=1 axis = fig.add_axes([xpos,ypos,rti_width,rti_height]) ypos += rti_height beamInx = np.where(currentData.fov.beams == beam)[0] radar_lats = latCenter[beamInx,:] # Calculate terminator. ######################################################## if plotTerminator: daylight = np.ones([nrTimes,nrGates],np.bool) for tm_inx in range(nrTimes): tm = time[tm_inx] term_lons = lonCenter[beamInx,:] term_lats,tau,dec = daynight_terminator(tm,term_lons) if dec > 0: # NH Summer day_inx = np.where(radar_lats < term_lats)[1] else: day_inx = np.where(radar_lats > term_lats)[1] if day_inx.size != 0: daylight[tm_inx,day_inx] = False #Translate parameter information from short to long form. paramDict = getParamDict(metadata['param']) if paramDict.has_key('label'): param = paramDict['param'] cbarLabel = paramDict['label'] else: param = 'width' #Set param = 'width' at this point just to not screw up the colorbar function. cbarLabel = metadata['param'] #Set colorbar scale if not explicitly defined. if(scale == None): if autoScale: sd = stats.nanstd(np.abs(currentData.data),axis=None) mean = stats.nanmean(np.abs(currentData.data),axis=None) scMax = np.ceil(mean + 1.*sd) if np.min(currentData.data) < 0: scale = scMax*np.array([-1.,1.]) else: scale = scMax*np.array([0.,1.]) else: if paramDict.has_key('range'): scale = paramDict['range'] else: scale = [-200,200] #See if an axis is provided... if not, set one up! if axis==None: axis = fig.add_subplot(111) else: fig = axis.get_figure() if np.size(beamInx) == 0: beamInx = 0 beam = currentData.fov.beams[0] #Plot the SuperDARN data! verts = [] scan = [] data = np.squeeze(currentData.data[:,beamInx,:]) # The coords keyword needs to be tested better. For now, just allow 'gate' only. # Even in 'gate' mode, the geographic latitudes are plotted along with gate. # if coords == None and metadata.has_key('coords'): # coords = metadata['coords'] # if coords not in ['gate','range']: print 'Coords "%s" not supported for RTI plots. Using "gate".' % coords coords = 'gate' if coords == 'gate': rnge = currentData.fov.gates elif coords == 'range': rnge = currentData.fov.slantRFull[beam,:] xvec = [matplotlib.dates.date2num(x) for x in currentData.time] for tm in range(nrTimes-1): for rg in range(nrGates-1): if np.isnan(data[tm,rg]): continue if data[tm,rg] == 0 and not plotZeros: continue scan.append(data[tm,rg]) x1,y1 = xvec[tm+0],rnge[rg+0] x2,y2 = xvec[tm+1],rnge[rg+0] x3,y3 = xvec[tm+1],rnge[rg+1] x4,y4 = xvec[tm+0],rnge[rg+1] verts.append(((x1,y1),(x2,y2),(x3,y3),(x4,y4),(x1,y1))) if (cmap_handling == 'matplotlib') or autoScale: cmap = matplotlib.cm.jet bounds = np.linspace(scale[0],scale[1],256) norm = matplotlib.colors.BoundaryNorm(bounds,cmap.N) elif cmap_handling == 'superdarn': colors = 'lasse' cmap,norm,bounds = utils.plotUtils.genCmap(param,scale,colors=colors) pcoll = PolyCollection(np.array(verts),edgecolors='face',linewidths=0,closed=False,cmap=cmap,norm=norm,zorder=99) pcoll.set_array(np.array(scan)) axis.add_collection(pcoll,autolim=False) # Plot the terminator! ######################################################### if plotTerminator: # print 'Terminator functionality is disabled until further testing is completed.' term_verts = [] term_scan = [] rnge = currentData.fov.gates xvec = [matplotlib.dates.date2num(x) for x in currentData.time] for tm in range(nrTimes-1): for rg in range(nrGates-1): if daylight[tm,rg]: continue term_scan.append(1) x1,y1 = xvec[tm+0],rnge[rg+0] x2,y2 = xvec[tm+1],rnge[rg+0] x3,y3 = xvec[tm+1],rnge[rg+1] x4,y4 = xvec[tm+0],rnge[rg+1] term_verts.append(((x1,y1),(x2,y2),(x3,y3),(x4,y4),(x1,y1))) term_pcoll = PolyCollection(np.array(term_verts),facecolors='0.45',linewidth=0,zorder=99,alpha=0.25) axis.add_collection(term_pcoll,autolim=False) ################################################################################ if axvlines is not None: for line in axvlines: axis.axvline(line,color=axvline_color,ls='--') if xlim == None: xlim = (np.min(time),np.max(time)) axis.set_xlim(xlim) axis.xaxis.set_major_formatter(md.DateFormatter('%H:%M')) if plot_nr == 1: axis.set_xlabel('Time [UT]') if ylim == None: ylim = (np.min(rnge),np.max(rnge)) axis.set_ylim(ylim) if yticks != None: axis.set_yticks(yticks) # Y-axis labeling ############################################################## if coords == 'gate': if secondary_coords: if secondary_coords == 'range': if metadata['model'] == 'IS': axis.set_ylabel('Range Gate\nSlant Range [km]',labelpad=y_labelpad) elif metadata['model'] == 'GS': axis.set_ylabel('Range Gate\nGS Mapped Range [km]',labelpad=y_labelpad) else: geo_mag = 'Geo' if currentData.fov.coords == 'geo' else 'Mag' if metadata['model'] == 'IS': axis.set_ylabel('Range Gate\n%s Lat' % geo_mag,labelpad=y_labelpad) elif metadata['model'] == 'GS': axis.set_ylabel('Range Gate\nGS Mapped %s Lat' % geo_mag,labelpad=y_labelpad) yticks = axis.get_yticks() ytick_str = [] for tck in yticks: txt = [] txt.append('%d' % tck) rg_inx = np.where(tck == currentData.fov.gates)[0] if np.size(rg_inx) != 0: if secondary_coords == 'range': rang = currentData.fov.slantRCenter[beamInx,rg_inx] if np.isfinite(rang): txt.append('%d' % rang) else: txt.append('') else: lat = currentData.fov.latCenter[beamInx,rg_inx] if np.isfinite(lat): txt.append((u'%'+ytick_lat_format+'$^o$') % lat) else: txt.append('') txt = '\n'.join(txt) ytick_str.append(txt) axis.set_yticklabels(ytick_str,rotation=90,ma='center') else: axis.set_ylabel('Range Gate',labelpad=y_labelpad) elif coords == 'range': if secondary_coords == 'lat': # Use linear interpolation to get the latitude associated with a particular range. # Make sure we only include finite values in the interpolation function. finite_inx = np.where(np.isfinite(currentData.fov.latCenter[beam,:]))[0] tmp_ranges = currentData.fov.slantRCenter[beam,:][finite_inx] tmp_lats = currentData.fov.latCenter[beam,:][finite_inx] tmp_fn = sp.interpolate.interp1d(tmp_ranges,tmp_lats) yticks = axis.get_yticks() ytick_str = [] for tck in yticks: txt = [] # Append Latitude try: lat = tmp_fn(tck) txt.append((u'%'+ytick_lat_format+'$^o$') % lat) except: txt.append('') # Append Range txt.append('%d' % tck) txt = '\n'.join(txt) ytick_str.append(txt) #Put both lat and range on same string axis.set_yticklabels(ytick_str,rotation=90,ma='center') # Set yticklabels # Label y-axis geo_mag = 'Geo' if currentData.fov.coords == 'geo' else 'Mag' if metadata['model'] == 'IS': axis.set_ylabel('%s Latitude\nSlant Range [km]' % geo_mag,labelpad=y_labelpad) elif metadata['model'] == 'GS': axis.set_ylabel('GS Mapped %s Lat\nGS Mapped Range [km]' % geo_mag,labelpad=y_labelpad) else: if metadata['model'] == 'IS': axis.set_ylabel('Slant Range [km]',labelpad=y_labelpad) elif metadata['model'] == 'GS': axis.set_ylabel('GS Mapped Range [km]',labelpad=y_labelpad) axis.set_ylim(ylim) #Shade xBoundary Limits if xBoundaryLimits == None: if currentData.metadata.has_key('timeLimits'): xBoundaryLimits = currentData.metadata['timeLimits'] if xBoundaryLimits != None: gray = '0.75' # axis.axvspan(xlim[0],xBoundaryLimits[0],color=gray,zorder=150,alpha=0.5) # axis.axvspan(xBoundaryLimits[1],xlim[1],color=gray,zorder=150,alpha=0.5) axis.axvspan(xlim[0],xBoundaryLimits[0],color=gray,zorder=1) axis.axvspan(xBoundaryLimits[1],xlim[1],color=gray,zorder=1) axis.axvline(x=xBoundaryLimits[0],color='g',ls='--',lw=2,zorder=150) axis.axvline(x=xBoundaryLimits[1],color='g',ls='--',lw=2,zorder=150) #Shade yBoundary Limits if yBoundaryLimits == None: if currentData.metadata.has_key('gateLimits') and coords == 'gate': yBoundaryLimits = currentData.metadata['gateLimits'] if currentData.metadata.has_key('rangeLimits') and coords == 'range': yBoundaryLimits = currentData.metadata['rangeLimits'] if yBoundaryLimits != None: gray = '0.75' # axis.axhspan(ylim[0],yBoundaryLimits[0],color=gray,zorder=150,alpha=0.5) # axis.axhspan(yBoundaryLimits[1],ylim[1],color=gray,zorder=150,alpha=0.5) axis.axhspan(ylim[0],yBoundaryLimits[0],color=gray,zorder=1) axis.axhspan(yBoundaryLimits[1],ylim[1],color=gray,zorder=1) axis.axhline(y=yBoundaryLimits[0],color='g',ls='--',lw=2,zorder=150) axis.axhline(y=yBoundaryLimits[1],color='g',ls='--',lw=2,zorder=150) for bnd_item in yBoundaryLimits: if coords == 'gate': txt = [] txt.append('%d' % bnd_item) rg_inx = np.where(bnd_item == currentData.fov.gates)[0] if np.size(rg_inx) != 0: lat = currentData.fov.latCenter[beamInx,rg_inx] if np.isfinite(lat): txt.append(u'%.1f$^o$' % lat) else: txt.append('') txt = '\n'.join(txt) else: txt = '%.1f' % bnd_item axis.annotate(txt, (1.01, bnd_item) ,xycoords=('axes fraction','data'),rotation=90,ma='center') txt = 'Beam '+str(beam) axis.text(0.01,0.88,txt,size=22,ha='left',transform=axis.transAxes) # txt = 'Model: ' + metadata['model'] # axis.text(1.01, 0, txt, # horizontalalignment='left', # verticalalignment='bottom', # rotation='vertical', # size=model_text_size, # transform=axis.transAxes) if plot_cbar: cbw = 0.25 cbar_real_width = cbar_width*cbw cbar_xpos = (cbar_width-cbar_real_width)/2. + xpos + rti_width cbh = 0.80 cbar_real_height = rti_height_total * cbh cbar_ypos = (rti_height_total-cbar_real_height)/2. + pos[1] cax = fig.add_axes([cbar_xpos,cbar_ypos,cbar_real_width,cbar_real_height]) # cbar = fig.colorbar(pcoll,orientation='vertical',shrink=cbar_shrink,fraction=cbar_fraction) cbar = fig.colorbar(pcoll,orientation='vertical',cax=cax) cbar.set_label(cbarLabel) if cbar_ticks is None: labels = cbar.ax.get_yticklabels() labels[-1].set_visible(False) else: cbar.set_ticks(cbar_ticks) if currentData.metadata.has_key('gscat'): if currentData.metadata['gscat'] == 1: cbar.ax.text(0.5,cbar_gstext_offset,'Ground\nscat\nonly',ha='center',fontsize=cbar_gstext_fontsize) # Plot frequency and noise information. ######################################## if hasattr(dataObject,'prm') and plot_info: curr_xlim = axis.get_xlim() curr_xticks = axis.get_xticks() pos0 = [xpos,ypos,rti_width,info_height/2.] plotFreq(fig,dataObject.prm.time,dataObject.prm.tfreq,dataObject.prm.nave,pos=pos0,xlim=curr_xlim,xticks=curr_xticks) ypos += info_height/2. pos0 = [xpos,ypos,rti_width,info_height/2.] plotNoise(fig,dataObject.prm.time,dataObject.prm.noisesky,dataObject.prm.noisesearch,pos=pos0,xlim=curr_xlim,xticks=curr_xticks) ypos += info_height/2. # Put a title on the RTI Plot. ################################################# if plot_title: title_y = ypos + 0.015 xmin = pos[0] xmax = pos[0] + pos[2] txt = metadata['name']+' ('+metadata['fType']+')' fig.text(xmin,title_y,txt,ha='left',weight=550) txt = [] txt.append(xlim[0].strftime('%Y %b %d %H%M UT - ')+xlim[1].strftime('%Y %b %d %H%M UT')) txt.append(currentData.history[max(currentData.history.keys())]) #Label the plot with the current level of data processing. txt = '\n'.join(txt) fig.text((xmin+xmax)/2.,title_y,txt,weight=550,size='large',ha='center')
def overlayFan(myData, myMap, myFig, param, coords='geo', gsct=0, site=None, fov=None, gs_flg=[], fill=True, velscl=1000., dist=1000., cmap=None, norm=None, alpha=1): """A function of overlay radar scan data on a map Parameters ---------- myData : pydarn.sdio.radDataTypes.scanData or pydarn.sdio.radDataTypes.beamData or list of pydarn.sdio.radDataTypes.beamData objects A radar beam object, a radar scanData object, or simply a list of radar beams myMap : The map we are plotting on myFig : Figure object that we are plotting to coords : Optional[str] The coordinates we are plotting in. Default: geo param : Optional[str] The parameter to be plotted, valid inputs are 'velocity', 'power', 'width', 'elevation', 'phi0'. default = 'velocity gsct : Optional[boolean] A flag indicating whether we are distinguishing ground scatter. default = 0 intensities : Optional[ ] A list of intensities (used for colorbar) fov : Optional[pydarn.radar.radFov.fov] A radar fov object gs_flg : Optional[ ] A list of gs flags, 1 per range gate fill : Optional[boolean] A flag indicating whether to plot filled or point RB cells. default = True velscl : Optional[float] The velocity to use as baseline for velocity vector length, only applicable if fill = 0. default = 1000 lines : Optional[ ] An array to have the endpoints of velocity vectors. only applicable if fill = 0. default = [] dist : Optional [float] The length in map projection coords of a velscl length velocity vector. default = 1000. km Returns ------- intensities pcoll lcoll Example ------- overlayFan(aBeam,myMap,param,coords,gsct=gsct,site=sites[i],fov=fovs[i], verts=verts,intensities=intensities,gs_flg=gs_flg) """ from davitpy import pydarn if(isinstance(myData, pydarn.sdio.beamData)): myData = [myData] if(site is None): site = pydarn.radar.site(radId=myData[0].stid, dt=myData[0].time) if(fov is None): fov = pydarn.radar.radFov.fov(site=site, rsep=myData[0].prm.rsep, ngates=myData[0].prm.nrang + 1, nbeams=site.maxbeam, coords=coords, date_time=myData[0].time) gs_flg, lines = [], [] if fill: verts, intensities = [], [] else: verts, intensities = [[], []], [[], []] # loop through gates with scatter for myBeam in myData: for k in range(0, len(myBeam.fit.slist)): if myBeam.fit.slist[k] not in fov.gates: continue r = myBeam.fit.slist[k] if fill: x1, y1 = myMap(fov.lonFull[myBeam.bmnum, r], fov.latFull[myBeam.bmnum, r]) x2, y2 = myMap(fov.lonFull[myBeam.bmnum, r + 1], fov.latFull[myBeam.bmnum, r + 1]) x3, y3 = myMap(fov.lonFull[myBeam.bmnum + 1, r + 1], fov.latFull[myBeam.bmnum + 1, r + 1]) x4, y4 = myMap(fov.lonFull[myBeam.bmnum + 1, r], fov.latFull[myBeam.bmnum + 1, r]) # save the polygon vertices verts.append(((x1, y1), (x2, y2), (x3, y3), (x4, y4), (x1, y1))) # save the param to use as a color scale if(param == 'velocity'): intensities.append(myBeam.fit.v[k]) elif(param == 'power'): intensities.append(myBeam.fit.p_l[k]) elif(param == 'width'): intensities.append(myBeam.fit.w_l[k]) elif(param == 'elevation' and myBeam.prm.xcf): intensities.append(myBeam.fit.elv[k]) elif(param == 'phi0' and myBeam.prm.xcf): intensities.append(myBeam.fit.phi0[k]) else: x1, y1 = myMap(fov.lonCenter[myBeam.bmnum, r], fov.latCenter[myBeam.bmnum, r]) verts[0].append(x1) verts[1].append(y1) x2, y2 = myMap(fov.lonCenter[myBeam.bmnum, r + 1], fov.latCenter[myBeam.bmnum, r + 1]) theta = math.atan2(y2 - y1, x2 - x1) x2, y2 = x1 + myBeam.fit.v[k] / velscl * (-1.0) * \ math.cos(theta) * dist, y1 + myBeam.fit.v[k] / velscl * \ (-1.0) * math.sin(theta) * dist lines.append(((x1, y1), (x2, y2))) # save the param to use as a color scale if(param == 'velocity'): intensities[0].append(myBeam.fit.v[k]) elif(param == 'power'): intensities[0].append(myBeam.fit.p_l[k]) elif(param == 'width'): intensities[0].append(myBeam.fit.w_l[k]) elif(param == 'elevation' and myBeam.prm.xcf): intensities[0].append(myBeam.fit.elv[k]) elif(param == 'phi0' and myBeam.prm.xcf): intensities[0].append(myBeam.fit.phi0[k]) if(myBeam.fit.p_l[k] > 0): intensities[1].append(myBeam.fit.p_l[k]) else: intensities[1].append(0.) if(gsct): gs_flg.append(myBeam.fit.gflg[k]) # do the actual overlay if(fill): # if we have data if(verts != []): if(gsct == 0): inx = numpy.arange(len(verts)) else: inx = numpy.where(numpy.array(gs_flg) == 0) x = PolyCollection(numpy.array(verts)[numpy.where( numpy.array(gs_flg) == 1)], facecolors='.3', linewidths=0, zorder=5, alpha=alpha) myFig.gca().add_collection(x, autolim=True) pcoll = PolyCollection(numpy.array(verts)[inx], edgecolors='face', linewidths=0, closed=False, zorder=4, alpha=alpha, cmap=cmap, norm=norm) # set color array to intensities pcoll.set_array(numpy.array(intensities)[inx]) myFig.gca().add_collection(pcoll, autolim=True) return intensities, pcoll else: # if we have data if(verts != [[], []]): if(gsct == 0): inx = numpy.arange(len(verts[0])) else: inx = numpy.where(numpy.array(gs_flg) == 0) # plot the ground scatter as open circles x = myFig.scatter(numpy.array(verts[0])[numpy.where( numpy.array(gs_flg) == 1)], numpy.array(verts[1])[numpy.where( numpy.array(gs_flg) == 1)], s=.1 * numpy.array(intensities[1])[ numpy.where(numpy.array(gs_flg) == 1)], zorder=5, marker='o', linewidths=.5, facecolors='w', edgecolors='k') myFig.gca().add_collection(x, autolim=True) # plot the i-s as filled circles ccoll = myFig.gca().scatter(numpy.array(verts[0])[inx], numpy.array(verts[1])[inx], s=.1 * numpy.array( intensities[1])[inx], zorder=10, marker='o', linewidths=.5, edgecolors='face', cmap=cmap, norm=norm) # set color array to intensities ccoll.set_array(numpy.array(intensities[0])[inx]) myFig.gca().add_collection(ccoll) # plot the velocity vectors lcoll = LineCollection(numpy.array(lines)[inx], linewidths=.5, zorder=12, cmap=cmap, norm=norm) lcoll.set_array(numpy.array(intensities[0])[inx]) myFig.gca().add_collection(lcoll) return intensities, lcoll
def overlayFan(myData,myMap,myFig,param,coords='geo',gsct=0,site=None,\ fov=None,gs_flg=[],fill=True,velscl=1000.,dist=1000., cmap=None,norm=None,alpha=1): """A function of overlay radar scan data on a map **Args**: * **myData (:class:`pydarn.sdio.radDataTypes.scanData` or :class:`pydarn.sdio.radDataTypes.beamData` or list of :class:`pydarn.sdio.radDataTypes.beamData` objects)**: a radar beam object, a radar scanData object, or simply a list of radar beams * **myMap**: the map we are plotting on * **[param]**: the parameter we are plotting * **[coords]**: the coordinates we are plotting in * **[param]**: the parameter to be plotted, valid inputs are 'velocity', 'power', 'width', 'elevation', 'phi0'. default = 'velocity * **[gsct]**: a flag indicating whether we are distinguishing ground scatter. default = 0 * **[intensities]**: a list of intensities (used for colorbar) * **[fov]**: a radar fov object * **[gs_flg]**: a list of gs flags, 1 per range gate * **[fill]**: a flag indicating whether to plot filled or point RB cells. default = True * **[velscl]**: the velocity to use as baseline for velocity vector length, only applicable if fill = 0. default = 1000 * **[lines]**: an array to have the endpoints of velocity vectors. only applicable if fill = 0. default = [] * **[dist]**: the length in map projection coords of a velscl length velocity vector. default = 1000. km **OUTPUTS**: NONE **EXAMPLE**: :: overlayFan(aBeam,myMap,param,coords,gsct=gsct,site=sites[i],fov=fovs[i],\ verts=verts,intensities=intensities,gs_flg=gs_flg) Written by AJ 20121004 """ if(site == None): site = pydarn.radar.site(radId=myData[0].stid, dt=myData[0].time) if(fov == None): fov = pydarn.radar.radFov.fov(site=site,rsep=myData[0].prm.rsep,\ ngates=myData[0].prm.nrang+1,nbeams= site.maxbeam,coords=coords) if(isinstance(myData,pydarn.sdio.beamData)): myData = [myData] gs_flg,lines = [],[] if fill: verts,intensities = [],[] else: verts,intensities = [[],[]],[[],[]] #loop through gates with scatter for myBeam in myData: for k in range(0,len(myBeam.fit.slist)): if myBeam.fit.slist[k] not in fov.gates: continue r = myBeam.fit.slist[k] if fill: x1,y1 = myMap(fov.lonFull[myBeam.bmnum,r],fov.latFull[myBeam.bmnum,r]) x2,y2 = myMap(fov.lonFull[myBeam.bmnum,r+1],fov.latFull[myBeam.bmnum,r+1]) x3,y3 = myMap(fov.lonFull[myBeam.bmnum+1,r+1],fov.latFull[myBeam.bmnum+1,r+1]) x4,y4 = myMap(fov.lonFull[myBeam.bmnum+1,r],fov.latFull[myBeam.bmnum+1,r]) #save the polygon vertices verts.append(((x1,y1),(x2,y2),(x3,y3),(x4,y4),(x1,y1))) #save the param to use as a color scale if(param == 'velocity'): intensities.append(myBeam.fit.v[k]) elif(param == 'power'): intensities.append(myBeam.fit.p_l[k]) elif(param == 'width'): intensities.append(myBeam.fit.w_l[k]) elif(param == 'elevation' and myBeam.prm.xcf): intensities.append(myBeam.fit.elv[k]) elif(param == 'phi0' and myBeam.prm.xcf): intensities.append(myBeam.fit.phi0[k]) else: x1,y1 = myMap(fov.lonCenter[myBeam.bmnum,r],fov.latCenter[myBeam.bmnum,r]) verts[0].append(x1) verts[1].append(y1) x2,y2 = myMap(fov.lonCenter[myBeam.bmnum,r+1],fov.latCenter[myBeam.bmnum,r+1]) theta = math.atan2(y2-y1,x2-x1) x2,y2 = x1+myBeam.fit.v[k]/velscl*(-1.0)*math.cos(theta)*dist,y1+myBeam.fit.v[k]/velscl*(-1.0)*math.sin(theta)*dist lines.append(((x1,y1),(x2,y2))) #save the param to use as a color scale if(param == 'velocity'): intensities[0].append(myBeam.fit.v[k]) elif(param == 'power'): intensities[0].append(myBeam.fit.p_l[k]) elif(param == 'width'): intensities[0].append(myBeam.fit.w_l[k]) elif(param == 'elevation' and myBeam.prm.xcf): intensities[0].append(myBeam.fit.elv[k]) elif(param == 'phi0' and myBeam.prm.xcf): intensities[0].append(myBeam.fit.phi0[k]) if(myBeam.fit.p_l[k] > 0): intensities[1].append(myBeam.fit.p_l[k]) else: intensities[1].append(0.) if(gsct): gs_flg.append(myBeam.fit.gflg[k]) #do the actual overlay if(fill): #if we have data if(verts != []): if(gsct == 0): inx = numpy.arange(len(verts)) else: inx = numpy.where(numpy.array(gs_flg)==0) x = PolyCollection(numpy.array(verts)[numpy.where(numpy.array(gs_flg)==1)], facecolors='.3',linewidths=0,zorder=5,alpha=alpha) myFig.gca().add_collection(x, autolim=True) pcoll = PolyCollection(numpy.array(verts)[inx], edgecolors='face',linewidths=0,closed=False,zorder=4, alpha=alpha,cmap=cmap,norm=norm) #set color array to intensities pcoll.set_array(numpy.array(intensities)[inx]) myFig.gca().add_collection(pcoll, autolim=True) return intensities,pcoll else: #if we have data if(verts != [[],[]]): if(gsct == 0): inx = numpy.arange(len(verts[0])) else: inx = numpy.where(numpy.array(gs_flg)==0) #plot the ground scatter as open circles x = myFig.scatter(numpy.array(verts[0])[numpy.where(numpy.array(gs_flg)==1)],\ numpy.array(verts[1])[numpy.where(numpy.array(gs_flg)==1)],\ s=.1*numpy.array(intensities[1])[numpy.where(numpy.array(gs_flg)==1)],\ zorder=5,marker='o',linewidths=.5,facecolors='w',edgecolors='k') myFig.gca().add_collection(x, autolim=True) #plot the i-s as filled circles ccoll = myFig.gca().scatter(numpy.array(verts[0])[inx],numpy.array(verts[1])[inx], \ s=.1*numpy.array(intensities[1])[inx],zorder=10,marker='o',linewidths=.5, \ edgecolors='face',cmap=cmap,norm=norm) #set color array to intensities ccoll.set_array(numpy.array(intensities[0])[inx]) myFig.gca().add_collection(ccoll) #plot the velocity vectors lcoll = LineCollection(numpy.array(lines)[inx],linewidths=.5,zorder=12,cmap=cmap,norm=norm) lcoll.set_array(numpy.array(intensities[0])[inx]) myFig.gca().add_collection(lcoll) return intensities,lcoll
ni = ncv['nodeid'][:] xdict = dict(zip(ni,x)) ydict = dict(zip(ni,y)) s = ncv['hzg_ecosmo_sed2'][:] nv = ncv['nv'][:,:3]-1 verts=[] for nvi in nv: verts.append([(xdict[i+1],ydict[i+1]) for i in nvi]) verts=asarray(verts) f=figure(figsize=(10,10)) p = PolyCollection(verts,closed=True,edgecolor='none') p.set_array(s[0]) p.set_cmap(cm.RdYlBu_r) pn = PolyCollection(verts,closed=True,edgecolor='none') pn.set_array(arange(len(s[0]))) pn.set_cmap(cm.RdYlBu_r) ax=axes([0.1,0.75,0.88,0.2]) ax.add_collection(p,autolim=True) autoscale() colorbar(p) ax=axes([0.1,0.25,0.88,0.2]) ax.add_collection(pn,autolim=True) autoscale() colorbar(pn)
def tile(self, x, y, w, h, color=None, anchor='center', edgecolors='face', linewidth=0.8, **kwargs): """Plot rectanguler tiles based onto these `Axes`. ``x`` and ``y`` give the anchor point for each tile, with ``w`` and ``h`` giving the extent in the X and Y axis respectively. Parameters ---------- x, y, w, h : `array_like`, shape (n, ) Input data color : `array_like`, shape (n, ) Array of amplitudes for tile color anchor : `str`, optional Anchor point for tiles relative to ``(x, y)`` coordinates, one of - ``'center'`` - center tile on ``(x, y)`` - ``'ll'`` - ``(x, y)`` defines lower-left corner of tile - ``'lr'`` - ``(x, y)`` defines lower-right corner of tile - ``'ul'`` - ``(x, y)`` defines upper-left corner of tile - ``'ur'`` - ``(x, y)`` defines upper-right corner of tile **kwargs Other keywords are passed to :meth:`~matplotlib.collections.PolyCollection` Returns ------- collection : `~matplotlib.collections.PolyCollection` the collection of tiles drawn Examples -------- >>> import numpy >>> from matplotlib import pyplot >>> import gwpy.plot # to get gwpy's Axes >>> x = numpy.arange(10) >>> y = numpy.arange(x.size) >>> w = numpy.ones_like(x) * .8 >>> h = numpy.ones_like(x) * .8 >>> fig = pyplot.figure() >>> ax = fig.gca() >>> ax.tile(x, y, w, h, anchor='ll') >>> pyplot.show() """ # get color and sort if color is not None and kwargs.get('c_sort', True): sortidx = color.argsort() x = x[sortidx] y = y[sortidx] w = w[sortidx] h = h[sortidx] color = color[sortidx] # define how to make a polygon for each tile if anchor == 'll': def _poly(x, y, w, h): return ((x, y), (x, y+h), (x+w, y+h), (x+w, y)) elif anchor == 'lr': def _poly(x, y, w, h): return ((x-w, y), (x-w, y+h), (x, y+h), (x, y)) elif anchor == 'ul': def _poly(x, y, w, h): return ((x, y-h), (x, y), (x+w, y), (x+w, y-h)) elif anchor == 'ur': def _poly(x, y, w, h): return ((x-w, y-h), (x-w, y), (x, y), (x, y-h)) elif anchor == 'center': def _poly(x, y, w, h): return ((x-w/2., y-h/2.), (x-w/2., y+h/2.), (x+w/2., y+h/2.), (x+w/2., y-h/2.)) else: raise ValueError("Unrecognised tile anchor {!r}".format(anchor)) # build collection cmap = kwargs.pop('cmap', rcParams['image.cmap']) coll = PolyCollection((_poly(*tile) for tile in zip(x, y, w, h)), edgecolors=edgecolors, linewidth=linewidth, **kwargs) if color is not None: coll.set_array(color) coll.set_cmap(cmap) out = self.add_collection(coll) self.autoscale_view() return out
class Plot_2D(object): ''' NAME: Plot_2D PURPOSE: 2D map plotting of the CESM model output INPUTS: var: a 2D (or 1D for regional refinement) variable array to be plotted lons: longitude values (1-D array) for plotting in case of FV model lats: latitude values (1-D array) for plotting in case of FV model lon_range: 2-elements list with longitude ranges to plot lat_range: 2-elements list with latitude ranges to plot scrip_file: a scrip filename for regional refinement model output ax: Parent axes from which space for the plot will be drawn cmap: colormap for plot projection: map projection by cartopy.crs grid_line: plot grid lines? grid_line_lw: linewidth for grid line coast: draw coastlines country: draw country boundary lines state: draw state/province lines resolution: resolution of coast/country/state lines (10m, 50m, or 110m) feature_line_lw: linewidth for coast/country/state lines feature_color: color for coast/country/state lines lonlat_line: draw longitue & latitude lines? lon_interval: longitude lines interval lat_interval: latitude lines interval font_family: font family being used for the plot label_size: label size for the plot (longitude & latitude) colorbar: add colorbar? log_scale: log_scale? (True) or linear_scale? (False) log_scale_min: if provided, this value is used for the closest tick to zero used for maximum tick value < 10^(-1) ignored if both cmin and cmax are positive ignored if colorticks is specified diff: if True, absolute values of cmin and cmax set to be the same orientation: colorbar orientation - horizontal or vertical shrink: fraction by which to multiply the size of the colorbar pad: fraction of original axes between colorbar and image axes fraction: fraction of original axis to use for colorbar extend: If not 'neither', make pointed ends for out-of-range values colorticks: list of ticks being used for colorbar colorlabels: list of tick labels being used for colorbar pretty_tick: If True, colorbar ticks are specially calculated nticks: number of ticks, being ignored when colorticks are specified cmax: maximum value for the plot and colorbar cmin: minimum value for the plot and colorbar title: plot title title_size: font size of the title title_bold: if True, set title font to bold unit: unit next to the colorbar unit_size: font size of the unit unit_bold: if True, set unit font to bold unit_italic: if True, set unit font to italic unit_offset: to make adjustment to colorbar position verbose: Display detailed information on what is being done ''' def __init__(self, var, lons=None, lats=None, lon_range=[-180, 180], lat_range=[-90, 90], scrip_file="", ax=None, cmap=None, projection=ccrs.PlateCarree(), grid_line=False, grid_line_lw=1, coast=True, country=True, state=False, resolution="10m", feature_line_lw=0.5, feature_color="black", lonlat_line=True, lon_interval=None, lat_interval=None, font_family="STIXGeneral", label_size=15, colorbar=True, log_scale=False, log_scale_min=None, diff=False, orientation="horizontal", shrink=0.8, pad=0.12, fraction=0.1, extend='both', colorticks=None, colorlabels=None, pretty_tick=True, nticks=None, cmax=None, cmin=None, title="", title_size=20, title_bold=False, unit="", unit_size=15, unit_bold=False, unit_italic=True, unit_offset=[0.0, 0.0], verbose=False): # ======================================================================== # ===== Error check and pass input values to class-accessible values ===== # ======================================================================== # variable dimension check if (np.ndim(var) > 2) or (np.ndim(var) < 1): raise ValueError('"var" must be 1-D (SE) or 2-D (FV) array') # xarray, lon, and lat check if type(var) in [xr.core.dataset.Dataset, xr.core.dataarray.DataArray]: if np.ndim(var) == 2: # FV results self.model_type = 'FV' if verbose: print( '"var" is a xarray variable, longitude and latitude values ' + \ 'are being automatically assigned by xarray dimension variables') if lons != None: print( 'Warning: "lons" is assigned but not used ' + \ 'because xarray itself has longitude values') if lats != None: print( 'Warning: "lats" is assigned but not used ' + \ 'because xarray itself has longitude values') self.var = np.copy(var.values) self.lon = np.copy(var.lon.values) self.lat = np.copy(var.lat.values) else: # SE results self.model_type = 'SE' self.var = np.copy(var.values) else: self.var = np.copy(var) if np.ndim(var) == 2: # FV results self.model_type = 'FV' if np.shape(lons) == (): raise ValueError( '"lons" must be provided for FV model output') else: self.lon = np.copy(lons) if np.shape(lats) == (): raise ValueError( '"lats" must be provided for FV model output') else: self.lat = np.copy(lats) else: # SE results self.model_type = 'SE' # lon_range dimension check if len(lon_range) != 2: raise ValueError( 'Check lon_range!' + '\n' + \ 'Current Values:', lon_range) else: self.lon_range = lon_range # lat_range dimension check if len(lat_range) != 2: raise ValueError( 'Check lat_range!' + '\n' + \ 'Current Values:', lat_range) else: self.lat_range = lat_range # Read scrip file in case of SE model output if self.model_type == 'SE': if scrip_file == "": raise ValueError( '"scrip_file" must be specified for SE model output') if type(scrip_file) != str: raise ValueError('"scrip_file" must be provided as "string"') if verbose: print("Read SCRIP file:", scrip_file) ds_scrip = xr.open_dataset(scrip_file) self.corner_lon = np.copy(ds_scrip.grid_corner_lon.values) self.corner_lat = np.copy(ds_scrip.grid_corner_lat.values) self.center_lon = np.copy(ds_scrip.grid_center_lon.values) self.center_lat = np.copy(ds_scrip.grid_center_lat.values) # Color map check if cmap == None: if diff: #self.cmap = cm.seismic self.cmap = cm.bwr else: self.cmap = cm.jet else: self.cmap = cmap # axis check if ax == None: self.fig = plt.figure(figsize=(8, 5)) ax = self.fig.add_subplot(1, 1, 1, projection=projection) else: self.fig = ax.figure self.ax = ax # nticks check, assign the base value if None if nticks == None: if log_scale: self.nticks = 7 else: self.nticks = 5 else: self.nticks = nticks # Pass input keywords self.scrip_file = scrip_file self.font_family = font_family self.projection = projection self.verbose = verbose self.grid_line = grid_line self.grid_line_lw = grid_line_lw self.label_size = label_size self.coast = coast self.country = country self.state = state self.resolution = resolution self.feature_line_lw = feature_line_lw self.feature_color = feature_color self.lonlat_line = lonlat_line self.lon_interval = lon_interval self.lat_interval = lat_interval self.colorbar = colorbar self.log_scale = log_scale self.log_scale_min = log_scale_min self.orientation = orientation self.shrink = shrink self.pad = pad self.fraction = fraction self.extend = extend self.colorticks = colorticks self.colorlabels = colorlabels self.pretty_tick = pretty_tick self.cmax = cmax self.cmin = cmin self.title = title self.title_size = title_size self.title_bold = title_bold self.unit = unit self.unit_size = unit_size self.unit_bold = unit_bold self.unit_italic = unit_italic self.unit_offset = unit_offset # === END Error check and pass input values to class-accessible values === # ======================================================================== # ======================================================================= # ============================ Initial Setup ============================ # ======================================================================= # If lon_range doesn't match longitude values, # shift longitude values by 180 degree if self.model_type == 'FV': # 2D FV model output if ((np.min(self.lon_range) < 0) & (np.max(self.lon) > 180)): self.lon[self.lon > 180.] -= 360. if verbose: print("FV model: Shift longitude values by 180 degree") else: # 1D SE model output if ((np.min(self.lon_range) < 0) & (np.max(self.corner_lon) > 180)): self.corner_lon[self.corner_lon > 180.] -= 360. if verbose: print("SE model: Shift longitude values by 180 degree") # automatically set longitude and latitude intervals if self.lonlat_line: if self.lon_interval == None: lon_length = lon_range[1] - lon_range[0] self.lon_interval = np.around(lon_length / 6.) if self.lon_interval < 1: self.lon_interval = 1 if self.lat_interval == None: lat_length = lat_range[1] - lat_range[0] self.lat_interval = np.around(lat_length / 6.) if self.lat_interval < 1: self.lat_interval = 1 # set vertices for SE model output if self.model_type == 'SE': self.lons_corners = np.copy( self.corner_lon.reshape(self.corner_lon.shape[0], self.corner_lon.shape[1], 1)) self.lats_corners = np.copy( self.corner_lat.reshape(self.corner_lat.shape[0], self.corner_lat.shape[1], 1)) self.lons_corners[self.lons_corners > 180.] -= 360 self.center_lon[self.center_lon > 180.] -= 360 self.lons_corners_add = [] self.lats_corners_add = [] self.var_add = [] # For longitudes -180, 180 for i, cenlon in enumerate(self.center_lon): lon_maxmin = np.max( self.lons_corners[i,:,:] ) - \ np.min( self.lons_corners[i,:,:] ) if (lon_maxmin > 180): if np.mean(self.lons_corners[i, :, :]) <= 0: inds2 = np.where(self.lons_corners[i, :, :] < 0)[0] tmp_lons_corners = np.copy(self.lons_corners[i, :]) tmp_lons_corners[inds2] = 180. self.lons_corners_add.append(tmp_lons_corners) self.lats_corners_add.append(self.lats_corners[i, :]) inds = np.where(self.lons_corners[i, :, :] > 0)[0] self.lons_corners[i, inds] = -180. self.var_add.append(self.var[i]) elif np.mean(self.lons_corners[i, :, :]) > 0: inds2 = np.where(self.lons_corners[i, :, :] > 0)[0] tmp_lons_corners = np.copy(self.lons_corners[i, :]) tmp_lons_corners[inds2] = -180. self.lons_corners_add.append(tmp_lons_corners) self.lats_corners_add.append(self.lats_corners[i, :]) inds = np.where(self.lons_corners[i, :, :] < 0)[0] self.lons_corners[i, inds] = 180. self.var_add.append(self.var[i]) self.lons_corners = np.concatenate( (self.lons_corners, np.array(self.lons_corners_add)), axis=0) self.lats_corners = np.concatenate( (self.lats_corners, np.array(self.lats_corners_add)), axis=0) self.var = np.concatenate((self.var, np.array(self.var_add)), axis=0) self.verts = np.concatenate((self.lons_corners, self.lats_corners), axis=2) # set plot color properties (FV model output) if self.model_type == 'FV': self.lon_inds = np.where( ( self.lon >= self.lon_range[0] ) & \ ( self.lon <= self.lon_range[-1] ) )[0] self.lat_inds = np.where( ( self.lat >= self.lat_range[0] ) & \ ( self.lat <= self.lat_range[-1] ) )[0] self.var_slice = self.var[self.lat_inds[0]:self.lat_inds[-1] + 1, self.lon_inds[0]:self.lon_inds[-1] + 1] elif self.model_type == 'SE': self.ncol_inds = np.where( ( self.center_lon >= self.lon_range[0] ) & \ ( self.center_lon <= self.lon_range[-1] ) & \ ( self.center_lat >= self.lat_range[0] ) & \ ( self.center_lat <= self.lat_range[-1] ) )[0] self.corner_lon_slice = self.corner_lon[self.ncol_inds, :] self.corner_lat_slice = self.corner_lat[self.ncol_inds, :] self.center_lon_slice = self.center_lon[self.ncol_inds] self.center_lat_slice = self.center_lat[self.ncol_inds] self.var_slice = self.var[self.ncol_inds] # set colorbar properties self.kwd_pretty_tick = {} if not self.log_scale: if self.cmax == None: self.cmax = np.max(self.var_slice) else: self.kwd_pretty_tick['max_set'] = self.cmax if self.cmin == None: self.cmin = np.min(self.var_slice) else: self.kwd_pretty_tick['min_set'] = self.cmin if self.colorbar: # Automatically set tick values if self.pretty_tick: if np.shape(self.colorticks) == (): if self.log_scale: if self.cmin == None: self.cmin_od = \ np.floor(np.log10(np.abs(np.min( \ self.var_slice[self.var_slice != 0])))) self.cmin_sign = np.sign( np.min(self.var_slice[self.var_slice != 0])) else: self.cmin_od = np.floor(np.log10(np.abs( self.cmin))) self.cmin_sign = np.sign(self.cmin) if self.cmax == None: self.cmax_od = \ np.floor(np.log10(np.abs(np.max( \ self.var_slice[self.var_slice != 0])))) self.cmax_sign = np.sign( np.max( \ self.var_slice[self.var_slice != 0]) ) else: self.cmax_od = np.floor(np.log10(np.abs( self.cmax))) self.cmax_sign = np.sign(self.cmax) self.sign_sum = self.cmin_sign + self.cmax_sign if self.sign_sum in [1, 2]: if self.cmax_od > 3: nticks_init = self.cmax_od + 1 else: nticks_init = self.cmax_od - self.cmin_od + 1 if nticks_init > 6: Nticks_list = [5, 6, 7, 4] check_loop = True for nticks in Nticks_list: if self.cmax_od > 3: tmparray = np.linspace( 0, self.cmax_od, np.int(nticks)) else: tmparray = np.linspace( self.cmin_od, self.cmax_od, np.int(nticks)) checksum = np.sum( np.abs(tmparray - tmparray.astype('i'))) if np.abs(checksum) < 1e-7: check_loop = False break if check_loop: interval = np.ceil(self.cmax_od / 3).astype('I') tick_start = self.cmax_od colorticks_h = [] nticks = 0 while (tick_start > 0): colorticks_h.append(tick_start) tick_start -= interval self.colorticks = np.array( [0] + \ list(10**(np.flip(colorticks_h))) ) nticks = len(self.colorticks) else: if (self.cmax_od > 3): linticks = np.linspace( 0, self.cmax_od, num=np.int(nticks)) self.colorticks = np.array( [0] + \ list(10**(linticks[1:])) ) else: self.colorticks = np.logspace( self.cmin_od, self.cmax_od, num=np.int(nticks)) else: nticks = nticks_init linticks = np.linspace(self.cmin_od, self.cmax_od, np.int(nticks)) zero_ind = np.where(linticks == 0) self.colorticks = 10**(linticks) self.colorticks[zero_ind] = 0 if self.cmin_od < 0: self.linthresh = 10**(self.cmin_od) else: self.linthresh = 1e1 self.linscale = 1.5 elif self.sign_sum == 0: if (self.cmin_od > 0) or (self.cmax_od > 0): if diff: self.max_od = np.max( [self.cmin_od, self.cmax_od]) self.cmax_od = self.max_od self.cmin_od = self.max_od nticks_init = self.cmax_od - self.cmin_od * self.cmin_sign + 1 if nticks_init > 6: if diff: Nticks_list = [4, 5, 3, 6, 2] else: Nticks_list = [ 9, 8, 7, 6, 5, 10, 11, 12, 13, 4, 3, 2 ] check_loop = True for nticks in Nticks_list: if diff: tmparray = np.linspace( 0, self.cmax_od) else: tmparray = np.linspace( self.cmin_od * self.cmin_sign, self.cmax_od, np.int(nticks)) checksum = np.sum( np.abs(tmparray - tmparray.astype('i'))) if np.abs(checksum) < 1e-7: check_loop = False break if diff: if check_loop: interval = np.ceil(self.cmax_od / 3).astype('I') tick_start = self.cmax_od colorticks_h = [] nticks = 0 while (tick_start > 0): colorticks_h.append(tick_start) tick_start -= interval nticks += 1 self.colorticks = list(-10**(np.array(colorticks_h))) + \ [0] + list( 10**(np.flip(colorticks_h) ) ) nticks = len(self.colorticks) else: linticks_hl = np.linspace( -self.cmin_od, 0, nticks) linticks_hr = np.linspace( 0, self.cmax_od, nticks)[1:] self.colorticks = 10**( linticks_hl ) * -1 + \ 10**( linticks_hr ) self.colorticks[nticks] = 0 nticks = nticks * 2 - 1 else: linticks = tmparray zero_ind = np.where(linticks == 0) self.colorticks = 10**(np.abs( linticks)) * np.sign(linticks) self.colorticks[zero_ind] = 0 else: nticks = nticks_init linticks = np.linspace( self.cmin_od * self.cmin_sign, self.cmax_od, np.int(nticks)) zero_ind = np.where(linticks == 0) self.colorticks = 10**( linticks) * np.sign(linticks) self.colorticks[zero_ind] = 0 self.linthresh = 1e1 self.linscale = 1.5 else: if diff: self.cmax_od, self.cmin_od = \ np.max( [self.cmin_od, self.cmax_od] ), \ np.max( [self.cmin_od, self.cmax_od] ) if self.log_scale_min == None: self.min_order = np.min( [self.cmin_od, self.cmax_od]) if self.min_order > 4: self.cmin_p = 10 elif self.min_order > 0: self.cmin_p = 1 elif self.min_order <= 0: self.cmin_p = 10**( self.min_order) * 1e-4 else: self.cmin_p = self.log_scale_min self.colorticks = np.array([ -10**(self.cmin_od), -np.sqrt(10**(self.cmin_od) * self.cmin_p), -self.cmin_p, 0, self.cmin_p, np.sqrt(10**(self.cmax_od) * self.cmin_p), 10**(self.cmax_od) ]) nticks = 7 self.linthresh = self.cmin_p self.linscale = 1.5 elif self.sign_sum in [-2, -1]: nticks_init = self.cmax_od - self.cmin_od + 1 if nticks_init > 6: Nticks_list = [ 9, 8, 7, 6, 5, 10, 11, 12, 13, 4 ] for nticks in Nticks_list: tmparray = np.linspace( self.cmin_od, self.cmax_od, np.int(nticks)) checksum = np.sum( np.abs(tmparray - tmparray.astype('i'))) if np.abs(checksum) < 1e-7: break else: nticks = nticks_init self.colorticks = np.logspace(-self.cmin_od, -self.cmax_od, num=np.int(nticks)) self.linthresh = -self.cmax self.linscale = -self.cmax self.nticks = nticks else: self.cbprop = get_cbar_prop([self.var_slice], Ntick_set=self.nticks, **self.kwd_pretty_tick) self.colorticks = self.cbprop.colorticks self.colorlabels = self.cbprop.colorlabels self.cmin = self.colorticks[0] self.cmax = self.colorticks[-1] else: if np.shape(self.colorticks) == (): if self.log_scale: self.cmin = np.min(self.var_slice[self.var_slice != 0]) self.cmax = np.max(self.var_slice[self.var_slice != 0]) self.cmin_od = np.floor(np.log10(np.abs(self.cmin))) self.cmax_od = np.floor(np.log10(np.abs(self.cmax))) self.cmin_sign = np.sign(self.cmin) self.cmax_sign = np.sign(self.cmax) self.min_order = np.min([self.cmin_od, self.cmax_od]) if self.min_order > 4: self.cmin_p = 10 elif self.min_order > 0: self.cmin_p = 1 elif self.min_order <= 0: self.cmin_p = 10**(self.min_order) * 1e-4 self.colorticks = np.array([ self.cmin, -np.sqrt(-self.cmin * self.cmin_p), -self.cmin_p, 0, self.cmin_p, np.sqrt(self.cmax * self.cmin_p), self.cmax ]) self.linthresh = self.cmin_p self.linscale = 1.5 else: self.colorticks = np.linspace(self.cmin, self.cmax, self.nticks) else: self.linthresh = np.min( np.abs(self.colorticks[self.colorticks != 0])) self.linscale = 1.5 if np.shape(self.colorlabels) == (): if not self.log_scale: self.colorlabels = np.copy(self.colorticks) self.cmin = self.colorticks[0] self.cmax = self.colorticks[-1] # Adjust colorticks in case of maximum value > 1e3 # make colorlabels for log_scale plot if self.log_scale: if (self.sign_sum in [1, 2]) & (np.max(self.colorticks) > 1e3): ind_above_1 = np.where(self.colorticks > 1) self.colorticks = [0] + list(self.colorticks[ind_above_1]) self.nticks = len(self.colorticks) elif (self.sign_sum in [-1, -2 ]) & (np.min(self.colorticks) < 1e-3): ind_below_m1 = np.where(self.colorticks < -1) self.colorticks = list(self.colorticks[ind_below_m1]) + [0] self.nticks = len(self.colorticks) self.colorlabels = [] for ct in self.colorticks: if ct == 0: lbtmp = '0' else: if ct < 0: tmpind = 5 sign = "-" elif ct > 0: tmpind = 4 sign = "" if format(np.abs(ct), '.4e')[tmpind - 2:tmpind] == '00': lbtmp = format(ct, '.2e')[tmpind:] lbtmp = sign + '$\\mathdefault{' + lbtmp.replace('e','10^{')[:-2] + \ str(int(lbtmp[-2:])) + '}}$' else: lbtmp = format(ct, '.4e')[:tmpind] + format( ct, '.2e')[tmpind:] lbtmp = '$\\mathdefault{' + lbtmp.replace('e','\\times10^{')[:-2] + \ str(int(lbtmp[-2:])) + '}}$' self.colorlabels.append(lbtmp.replace('+', '')) # Dictionary declaration for keywords in external function call self.kwd_pcolormesh = {} self.kwd_polycollection = {} self.kwd_title = {} self.kwd_unit = {} # Construct pcolormesh dictionary if self.grid_line: if self.model_type == 'FV': self.kwd_pcolormesh['edgecolors'] = 'black' self.kwd_pcolormesh['lw'] = self.grid_line_lw elif self.model_type == 'SE': self.kwd_polycollection['edgecolor'] = 'black' self.kwd_polycollection['lw'] = self.grid_line_lw else: if self.model_type == 'SE': self.kwd_polycollection['edgecolor'] = 'face' if self.log_scale: #if self.model_type == 'FV': # # for compability with some matplotlib version try: self.kwd_pcolormesh['norm'] = \ matplotlib.colors.SymLogNorm( linthresh=self.linthresh, linscale=self.linscale, vmin=self.cmin, vmax=self.cmax ) self.kwd_polycollection['norm'] = \ matplotlib.colors.SymLogNorm( linthresh=self.linthresh, linscale=self.linscale, vmin=self.cmin, vmax=self.cmax ) except: self.kwd_pcolormesh['norm'] = \ matplotlib.colors.SymLogNorm( linthresh=self.linthresh, linscale=self.linscale, vmin=self.cmin, vmax=self.cmax, base=10 ) self.kwd_polycollection['norm'] = \ matplotlib.colors.SymLogNorm( linthresh=self.linthresh, linscale=self.linscale, vmin=self.cmin, vmax=self.cmax, base=10 ) #elif self.model_type == 'SE': # raise ValueError( 'log scale for SE model is currently not supported' ) if self.title != "": if self.title_bold: self.kwd_title['weight'] = 'semibold' if self.unit != "": if self.unit_bold: self.kwd_unit['weight'] = 'semibold' if self.unit_italic: self.kwd_unit['style'] = 'italic' # ========================== END Initial Setup ========================== # ======================================================================= # Call 2D plot code self.plot() # ======================================================================== # =============================== Plotting =============================== # ======================================================================== def plot(self): # === Set font family for the whole plot first === plt.rcParams['font.family'] = self.font_family # === FV model output (2D with longitude and latitude values) === if self.model_type == 'FV': self.im = self.ax.pcolormesh(self.lon, self.lat, self.var, cmap=self.cmap, transform=self.projection, vmin=self.cmin, vmax=self.cmax, **self.kwd_pcolormesh) elif self.model_type == 'SE': self.im = PolyCollection(self.verts, cmap=self.cmap, **self.kwd_polycollection) self.im.set_array(self.var) self.im.set_clim(vmin=self.cmin, vmax=self.cmax) self.ax.add_collection(self.im) # === Set longitude & Latitude labels & lines === self.ax.set_xlim(self.lon_range) self.ax.set_ylim(self.lat_range) self.ax.tick_params(labelsize=self.label_size) if self.coast: self.ax.coastlines(resolution=self.resolution, lw=self.feature_line_lw, color=self.feature_color) if self.country: self.ax.add_feature(cfeature.BORDERS.with_scale(self.resolution), lw=self.feature_line_lw, edgecolor=self.feature_color) if self.state: self.ax.add_feature(cfeature.STATES.with_scale(self.resolution), lw=self.feature_line_lw, edgecolor=self.feature_color) if self.lonlat_line: self.lonticklabel = np.arange(self.lon_range[0], self.lon_range[1] + 0.1, self.lon_interval) self.latticklabel = np.arange(self.lat_range[0], self.lat_range[1] + 0.1, self.lat_interval) self.ax.set_xticks(self.lonticklabel, crs=self.ax.projection) self.ax.set_yticks(self.latticklabel, crs=self.ax.projection) self.ax.set_xlabel('') self.ax.set_ylabel('') self.lon_formatter = LongitudeFormatter(zero_direction_label=True) self.lat_formatter = LatitudeFormatter() self.ax.xaxis.set_major_formatter(self.lon_formatter) self.ax.yaxis.set_major_formatter(self.lat_formatter) self.ax.grid(lw=1.0, color='black', alpha=0.5, linestyle=':') # === Set colorbar properties === self.cb = self.fig.colorbar(self.im, ax=self.ax, orientation=self.orientation, shrink=self.shrink, pad=self.pad, extend=self.extend, fraction=self.fraction, ticks=self.colorticks) self.cb.ax.tick_params(labelsize=self.label_size - 1) #if not (self.log_scale & self.pretty_tick): self.cb.ax.set_xticklabels(self.colorlabels, size=13) # === Add a title if specified === if self.title != "": self.ax.set_title(self.title, fontsize=self.title_size, fontfamily=self.font_family, **self.kwd_title) # === Add a unit if specified === if self.unit != "": self.cb.ax.text(1.02 + self.unit_offset[0], 1.0 + self.unit_offset[1], self.unit, size=self.unit_size, ha='left', va='top', transform=self.cb.ax.transAxes, **self.kwd_unit) # ============================= END Plotting ============================= # ======================================================================== # ===== Defining __call__ method ===== def __call__(self): print('=== var ===') print(np.shape(var))