Changeset 27198
- Timestamp:
- 08/10/22 06:04:05 (3 years ago)
- Location:
- issm/trunk-jpl/src/m/plot
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/m/plot/applyoptions.py
r27087 r27198 34 34 fontsize = options.getfieldvalue('fontsize', 8) 35 35 fontweight = options.getfieldvalue('fontweight', 'normal') 36 fontfamily = options.getfieldvalue('fontfamily', 'sans -serif')36 fontfamily = options.getfieldvalue('fontfamily', 'sans-serif') 37 37 font = { 38 38 'fontsize': fontsize, … … 186 186 if options.exist('cmap_set_under'): 187 187 cbar_extend += 2 188 # }}} 189 # {{{ contours 190 if options.exist('contourlevels'): 191 plot_contour(md, data, options, ax) 192 # }}} 193 # {{{ edgeoverlay 194 if options.exist('edgeoverlay'): 195 edgedata = options.getfieldvalue('edgeoverlay') 196 plot_edgeoverlay(md, edgedata, options, ax) 197 # }}} 198 # {{{ wrapping TODO 199 # }}} 200 # {{{ colorbar 201 if options.getfieldvalue('colorbar', 1) == 1: 188 189 # }}} 190 # {{{ colorbar extension 191 if options.exist('cbar_extend'): 192 extend = options.getfieldvalue('cbar_extend', 'neither') 193 else: 202 194 if cbar_extend == 0: 203 195 extend = 'neither' … … 208 200 elif cbar_extend == 3: 209 201 extend = 'both' 210 202 options.addfielddefault('cbar_extend', extend) 203 # }}} 204 # {{{ contours 205 if options.exist('contourlevels'): 206 plot_contour(md, data, options, ax) 207 # }}} 208 # {{{ edgeoverlay 209 if options.exist('edgeoverlay'): 210 edgedata = options.getfieldvalue('edgeoverlay') 211 plot_edgeoverlay(md, edgedata, options, ax) 212 # }}} 213 # {{{ wrapping TODO 214 # }}} 215 # {{{ colorbar 216 if options.getfieldvalue('colorbar', 1) == 1: 211 217 cb = mpl.colorbar.ColorbarBase(ax.cax, cmap=cmap, norm=norm, extend=extend) 212 218 if options.exist('alpha'): -
issm/trunk-jpl/src/m/plot/plot_edgeoverlay.py
r27088 r27198 3 3 import matplotlib.pyplot as plt 4 4 from processmesh import processmesh 5 from matplotlib import collections 6 from scipy.stats import percentileofscore 5 7 6 8 … … 13 15 See also: PLOTMODEL''' 14 16 17 # if md.mesh.numberofedges not in np.shape(datain): 18 # raise ValueError('Data must be defined on edges to be ploted as an edge overlay') 19 15 20 x, y, z, elements, is2d, isplanet = processmesh(md, [], options) 21 Edges = md.mesh.edges - 1 16 22 17 flags = datain > 6.7e-5 # this is appropriate for channel Area (perhaps) 18 hide = np.invert(flags) 23 #First we mask values under a given value define by quantiles 24 if options.exist('edgemin'): 25 minval = options.getfieldvalue('edgemin', 0) 26 minquant = percentileofscore(datain, minval, kind='weak') 27 minquant = minquant / 100 28 else: 29 minquant = 0.7 30 minval = np.quantile(datain, minquant) 31 print("For the overlay we plot values above {:.4g} wich corresponds to the {}% percentile".format(minval, minquant * 100)) 19 32 20 NodeMask = np.zeros(np.shape(md.mesh.x), dtype=bool) 21 HideElt = md.mesh.edges[np.where(hide), 0] - 1 22 NodeMask[HideElt] = True 23 MaskX = np.ma.array(x, mask=NodeMask) 24 MaskY = np.ma.array(y, mask=NodeMask) 33 flags = datain > minval #6.7e-5 # this is appropriate for channel Area (perhaps) 25 34 26 EdgeEnd = md.mesh.edges[:, 1] - 1 27 EdgeStart = md.mesh.edges[:, 0] - 1 28 quiverU = MaskX[EdgeEnd] - MaskX[EdgeStart] 29 quiverV = MaskY[EdgeEnd] - MaskY[EdgeStart] 35 edgetype = options.getfieldvalue('edgetype', 'thickness') 30 36 31 Masked = np.ma.masked_array(datain, mask=hide) 32 if options.exist('cedgelim'): 33 lims = options.getfieldvalue('cedgelim', [Masked.min(), Masked.max()]) 34 edgenorm = mpl.colors.Normalize(vmin=lims[0], vmax=lims[1]) 37 if edgetype == "color": 38 #create an nodewise dataset from edges 39 NodeMask = np.ones(np.shape(md.mesh.x), dtype=bool) 40 #We grab all the starts from the unmasked edges 41 Starters = Edges[np.where(flags), 0] 42 NodeMask[Starters] = False 43 Xstart = np.ma.array(x, mask=NodeMask) 44 Ystart = np.ma.array(y, mask=NodeMask) 45 46 NodeMask = np.ones(np.shape(md.mesh.x), dtype=bool) 47 Enders = Edges[np.where(flags), 1] 48 NodeMask[Enders] = False 49 Xend = np.ma.array(x, mask=NodeMask) 50 Yend = np.ma.array(y, mask=NodeMask) 51 52 #define vectors from the start and end point of the unmasked edges 53 EdgeEnd = Edges[:, 1] 54 EdgeStart = Edges[:, 0] 55 quiverU = np.ma.array(Xend[EdgeEnd] - Xstart[EdgeStart], mask=np.invert(flags)) 56 quiverV = np.ma.array(Yend[EdgeEnd] - Ystart[EdgeStart], mask=np.invert(flags)) 57 58 #mask out the values from the data and create colorscale 59 Masked = np.ma.masked_array(datain, mask=np.invert(flags)) 60 cbar_extend = 0 61 edgemap = plt.cm.get_cmap('inferno') 62 if options.exist('cedgeaxis'): 63 lims = options.getfieldvalue('cedgeaxis', [Masked.min(), Masked.max()]) 64 edgenorm = mpl.colors.Normalize(vmin=lims[0], vmax=lims[1]) 65 if lims[0] > Masked.min(): 66 edgemap.set_under('r') 67 cbar_extend += 2 68 if lims[1] < Masked.max(): 69 edgemap.set_over('k') 70 cbar_extend += 1 71 else: 72 edgenorm = mpl.colors.Normalize(vmin=Masked.min(), vmax=Masked.max()) 73 74 if cbar_extend == 0: 75 extend = 'neither' 76 elif cbar_extend == 1: 77 extend = 'max' 78 elif cbar_extend == 2: 79 extend = 'min' 80 elif cbar_extend == 3: 81 extend = 'both' 82 83 ax.quiver(Xstart[EdgeStart], Ystart[EdgeStart], quiverU, quiverV, datain, 84 units="xy", angles="xy", scale_units="xy", scale=1, 85 headwidth=0, headlength=0, width=100, headaxislength=0, 86 norm=edgenorm, cmap=edgemap) 87 88 #plt.colorbar(plt.cm.ScalarMappable(norm=edgenorm, cmap=edgemap), ax=ax, extend=extend, orientation='horizontal', anchor=(1, 0)) 89 cbarax = ax.inset_axes([0.02, 0.02, 0.96, 0.05]) 90 #inset_axes(ax, width="100%", height="5%", loc='lower center', borderpad=-5) 91 mpl.colorbar.ColorbarBase(cbarax, norm=edgenorm, cmap=edgemap, extend=extend, orientation='horizontal', ticklocation='top') 92 93 elif edgetype == 'thickness': 94 #First we classify a range 95 if options.exist('edgeranges'): 96 edgeranges = options.getfieldvalue('edgeranges', 2) 97 else: 98 edgeranges = 2 99 100 quantrange = np.linspace(minquant, 1, edgeranges + 1)[:-1] 101 flags = [] 102 legtext = [] 103 for Qindex, quantile in enumerate(quantrange): 104 if quantile < quantrange[-1]: 105 lowquant = np.quantile(datain, quantile) 106 highquant = np.quantile(datain, quantrange[Qindex + 1]) 107 flags.append(np.logical_and(datain >= lowquant, datain <= highquant)) 108 legtext.append('From {:.2g} to {:.2g}'. format(lowquant, highquant)) 109 else: 110 lowquant = np.quantile(datain, quantile) 111 flags.append((datain > lowquant)) 112 legtext.append('More than {:.2g}'.format(lowquant)) 113 114 flags = np.asarray(np.squeeze(flags)) 115 EdgeEnd = Edges[:, 1] 116 EdgeStart = Edges[:, 0] 117 118 for index in range(edgeranges): 119 linecol = [] 120 #We loop on the result and aonly add to a linecollection the flaged edges. 121 for datindex, datval in enumerate(datain): 122 if flags[index, datindex]: 123 linecol.append([(x[EdgeStart[datindex]], y[EdgeStart[datindex]]), 124 (x[EdgeEnd[datindex]], y[EdgeEnd[datindex]])]) 125 126 lc = collections.LineCollection(linecol, color='k', linewidth=0.5 + index, 127 label=legtext[index]) 128 ax.add_collection(lc) 129 130 ax.legend(title='Overlay') 131 35 132 else: 36 edgenorm = mpl.colors.Normalize(vmin=Masked.min(), vmax=Masked.max()) 37 edgemap = plt.cm.get_cmap('inferno') 38 39 ax.quiver(MaskX[EdgeStart], MaskY[EdgeStart], quiverU, quiverV, datain, 40 units="xy", angles="xy", scale_units="xy", scale=1, 41 headwidth=0, headlength=0, width=100, headaxislength=0, 42 norm=edgenorm, cmap=edgemap) 43 44 plt.colorbar(plt.cm.ScalarMappable(norm=edgenorm, cmap=edgemap), ax=ax) 133 print("Only 'color', and 'thickness' are accepted as edgeoverlay types") -
issm/trunk-jpl/src/m/plot/plot_manager.py
r26353 r27198 27 27 currently generated using matplotlib's AxesGrid toolkit. 28 28 29 'gridindex' is passed through to specialized plot* functions and 29 'gridindex' is passed through to specialized plot* functions and 30 30 applyoptions. 31 31 … … 89 89 # }}} 90 90 91 #process data and model92 91 x, y, z, elements, is2d, isplanet = processmesh(md, data, options) 93 92 data2, datatype = processdata(md, data, options) -
issm/trunk-jpl/src/m/plot/plot_unit.py
r27087 r27198 33 33 34 34 # colormap 35 # {{{ give number of colorlevels and transparency35 # give number of colorlevels and transparency {{{ 36 36 colorlevels = options.getfieldvalue('colorlevels', 128) 37 37 alpha = options.getfieldvalue('alpha', 1) 38 if alpha < 1: 39 antialiased = True 40 else: 41 antialiased = False 42 # }}} 43 # {{{ define wich colormap to use 38 # }}} 39 # define wich colormap to use {{{ 44 40 try: 45 41 defaultmap = plt.cm.get_cmap('viridis', colorlevels) … … 51 47 else: 52 48 cmap = getcolormap(options) 53 if options.exist('cmap_set_over'):54 over = options.getfieldvalue('cmap_set_over', 'k')55 cmap.set_over(over)56 if options.exist('cmap_set_under'):57 under = options.getfieldvalue('cmap_set_under', 'k')58 cmap.set_under(under)59 49 options.addfield('colormap', cmap) 60 50 # }}} 61 # {{{ if plotting only one of several layers reduce dataset, same for surface51 # if plotting only one of several layers reduce dataset, same for surface {{{ 62 52 if options.getfieldvalue('layer', 0) >= 1: 63 53 plotlayer = options.getfieldvalue('layer', 0) … … 68 58 data = data[(plotlayer - 1) * slicesize:plotlayer * slicesize] 69 59 # }}} 70 # {{{ Get the colormap limits60 # Get the colormap limits {{{ 71 61 dataspread = np.nanmax(data) - np.nanmin(data) 72 62 if dataspread != 0.: … … 77 67 if options.exist('caxis'): 78 68 lims = options.getfieldvalue('caxis', [np.nanmin(data), np.nanmax(data)]) 69 if lims[0] > np.nanmin(data): 70 options.addfielddefault('cmap_set_under', 'r') 71 if lims[1] < np.nanmax(data): 72 options.addfielddefault('cmap_set_over', 'k') 79 73 else: 80 74 if limextent == 0.: … … 85 79 else: 86 80 lims = [np.nanmin(data), np.nanmax(data)] 87 # }}} 88 # {{{ Set the spread of the colormap (default is normal 81 82 cbar_extend = 0 83 if options.exist('cmap_set_over'): 84 over = options.getfieldvalue('cmap_set_over', 'k') 85 cmap.set_over(over) 86 cbar_extend += 1 87 if options.exist('cmap_set_under'): 88 under = options.getfieldvalue('cmap_set_under', 'r') 89 cmap.set_under(under) 90 cbar_extend += 2 91 # }}} 92 93 # colorbar extension {{{ 94 if cbar_extend == 0: 95 extend = 'neither' 96 elif cbar_extend == 1: 97 extend = 'max' 98 elif cbar_extend == 2: 99 extend = 'min' 100 elif cbar_extend == 3: 101 extend = 'both' 102 options.addfielddefault('cbar_extend', extend) 103 # }}} 104 # Set the spread of the colormap (default is normal) {{{ 89 105 if options.exist('log'): 90 106 norm = mpl.colors.LogNorm(vmin=lims[0], vmax=lims[1]) … … 95 111 96 112 # Plot depending on the datatype 97 # {{{ data are on elements113 # data are on elements {{{ 98 114 if datatype == 1: 99 115 if is2d: … … 102 118 else: 103 119 triangles = mpl.tri.Triangulation(x, y, elements) 120 104 121 tri = ax.tripcolor(triangles, data, colorlevels, cmap=cmap, norm=norm, alpha=alpha, edgecolors=edgecolor) 105 122 else: … … 153 170 154 171 # }}} 155 # {{{ data are on nodes 156 172 # data are on nodes {{{ 157 173 elif datatype == 2: 158 174 if is2d: … … 162 178 else: 163 179 triangles = mpl.tri.Triangulation(x, y, elements) 164 #tri = ax.tricontourf(triangles, data, colorlevels, cmap = cmap, norm=norm, alpha = alpha) 165 if options.exist('log'): 166 if alpha < 1: #help with antialiasing 167 tri = ax.tricontour(triangles, data, colorlevels, cmap=cmap, norm=norm, alpha=0.1, antialiased=antialiased) 168 tri = ax.tricontourf(triangles, data, colorlevels, cmap=cmap, norm=norm, alpha=alpha, antialiased=antialiased) 180 if edgecolor == 'None': 181 tri = ax.tripcolor(triangles, data, cmap=cmap, norm=norm, alpha=alpha, shading='gouraud') 169 182 else: 170 if alpha < 1: #help with antialiasing 171 tri = ax.tricontour(triangles, data, colorlevels, cmap=cmap, norm=norm, alpha=0.1, antialiased=antialiased) 172 tri = ax.tricontourf(triangles, data, colorlevels, cmap=cmap, norm=norm, alpha=alpha, extend='both', antialiased=antialiased) 173 if edgecolor != 'None': 174 ax.triplot(x, y, elements, color=edgecolor) 183 tri = ax.tripcolor(triangles, data, cmap=cmap, norm=norm, alpha=alpha, edgecolors=edgecolor) 175 184 else: 176 185 #first deal with the colormap … … 178 187 loccmap.set_array(lims) 179 188 loccmap.set_clim(vmin=lims[0], vmax=lims[1]) 180 181 189 #deal with prism sides 182 190 recface = np.vstack((elements[:, 0], elements[:, 1], elements[:, 4], elements[:, 3])).T … … 215 223 216 224 # }}} 217 # {{{ plotting quiver225 # plotting quiver {{{ 218 226 elif datatype == 3: 219 227 if is2d: … … 223 231 return 224 232 # }}} 225 # {{{ plotting P1 Patch (TODO)233 # plotting P1 Patch (TODO) {{{ 226 234 elif datatype == 4: 227 235 print('plot_unit message: P1 patch plot not implemented yet') 228 236 return 229 237 # }}} 230 # {{{ plotting P0 Patch (TODO)238 # plotting P0 Patch (TODO) {{{ 231 239 elif datatype == 5: 232 240 print('plot_unit message: P0 patch plot not implemented yet') 233 241 return 234 242 # }}} 243 # plotting edges {{{ 244 elif datatype == 6: 245 if is2d: 246 triangles = mpl.tri.Triangulation(x, y, elements) 247 tri = ax.tripcolor(triangles, data, cmap=cmap, norm=norm, alpha=alpha, edgecolors=edgecolor) 248 249 else: 250 print("edge plotting is not implemented for 3D") 251 return 252 # }}} 235 253 else: 236 254 raise ValueError('datatype = %d not supported' % datatype) -
issm/trunk-jpl/src/m/plot/plotmodel.py
r27087 r27198 28 28 numberofplots = options.numberofplots 29 29 30 #get number of subplots 31 subplotwidth = ceil(sqrt(numberofplots)) 30 #get the "optimal" number of subfigures in a row/col 31 if (np.nanmax(md.mesh.x) - np.nanmin(md.mesh.x)) > (np.nanmax(md.mesh.y) - np.nanmin(md.mesh.y)): 32 maxrow = ceil(sqrt(numberofplots)) 33 maxcol = ceil(numberofplots / maxrow) 34 else: 35 maxcol = ceil(sqrt(numberofplots)) 36 maxrow = ceil(numberofplots / maxcol) 32 37 33 # TODO: Check that commenting this out is correct; we do not need a hold 34 # under matplotlib, right? 35 # 36 # #get hold 37 # hold = options.list[0].getfieldvalue('hold', False) 38 39 #if nrows and ncols specified, then bypass 38 #If any of nrows or ncols are given we use that 40 39 if options.list[0].exist('nrows'): 41 40 nrows = options.list[0].getfieldvalue('nrows') 42 nr = True 41 if options.list[0].exist('ncols'): 42 ncols = options.list[0].getfieldvalue('ncols') 43 else: 44 ncols = ceil(numberofplots / nrows) 45 elif options.list[0].exist('ncols'): 46 ncols = options.list[0].getfieldvalue('ncols') 47 nrows = ceil(numberofplots / ncols) 43 48 else: 44 nrows = np.ceil(numberofplots / subplotwidth) 45 nr = False 46 47 if options.list[0].exist('ncols'): 48 ncols = options.list[0].getfieldvalue('ncols') 49 nc = True 50 else: 51 ncols = int(subplotwidth) 52 nc = False 49 nrows = maxrow 50 ncols = maxcol 53 51 ncols = int(ncols) 54 52 nrows = int(nrows) 55 56 #check that nrows and ncols were given at the same time!57 if nr != nc:58 raise Exception('plotmodel error message: nrows and ncols need to be specified together, or not at all')59 53 60 54 # Go through plots -
issm/trunk-jpl/src/m/plot/processdata.py
r27087 r27198 8 8 datatype = 2 -> nodes 9 9 datatype = 3 -> node quivers 10 datatype = 4 -> patch 10 datatype = 4 -> P1 patch 11 datatype = 5 -> P0 patch 12 datatype = 6 -> edges 11 13 12 14 Usage: … … 24 26 else: 25 27 numberofvertices2d = np.nan 28 29 try: 30 numberofedges = md.mesh.numberofedges 31 except AttributeError: 32 numberofedges = np.nan 26 33 27 34 if options.exist('amr'): … … 52 59 # }}} 53 60 54 # 61 # log {{{ 55 62 if options.exist('log'): 56 63 cutoff = options.getfieldvalue('log', 1) … … 58 65 # }}} 59 66 60 # 67 # quiver plot {{{ 61 68 if datasize[1] > 1 and datasize[0] != numberofvertices + 1: 62 69 if datasize[0] == numberofvertices and datasize[1] in [2, 3]: … … 80 87 # }}} 81 88 82 # 89 # element data{{{ 83 90 if datasize[0] == numberofelements and datasize[1] == 1: 84 91 #initialize datatype if non patch … … 107 114 # }}} 108 115 109 # 110 if datasize[0] in [numberofvertices, numberofvertices2d] and datasize[1] == 1:116 # node data {{{ 117 elif datasize[0] in [numberofvertices, numberofvertices2d] and datasize[1] == 1: 111 118 datatype = 2 112 119 # AMR {{{ … … 115 122 procdata = procdata[nonan] 116 123 # }}} 117 # 124 # Mask {{{ 118 125 if options.exist('mask'): 119 126 flags = options.getfieldvalue('mask') … … 133 140 # }}} 134 141 135 # spc time series {{{ 136 if datasize[0] == numberofvertices + 1: 142 # edge data {{{ 143 elif datasize[0] in [numberofedges] and datasize[1] == 1: 144 datatype = 6 145 procdata = np.zeros((md.mesh.numberofelements)) 146 repeat = np.zeros((md.mesh.numberofelements)) 147 for index, edge in enumerate(md.mesh.edges[:, -2:]): 148 procdata[edge - 1] += data[index] * np.asarray(edge - 1 > -1, dtype=int) 149 repeat[edge - 1] += np.asarray(edge - 1 > -1, dtype=int) 150 procdata = procdata / repeat 151 152 # }}} 153 # }}} 154 155 # spc time series {{{ 156 elif datasize[0] == numberofvertices + 1: 137 157 datatype = 2 138 158 spccol = options.getfieldvalue('spccol', 0) … … 141 161 procdata = procdata[0:-1, spccol] 142 162 143 #mask?144 145 #layer projection?146 147 #control arrow density if quiver plot148 163 # }}} 149 164 150 # convert rank - 2 array to rank -1 {{{165 # convert rank -2 array to rank -1 {{{ 151 166 if np.ndim(procdata) == 2 and np.shape(procdata)[1] == 1: 152 167 procdata = procdata.reshape(-1, ) … … 169 184 procdata[np.isnan(procdata)] = nanfill 170 185 procdata = np.ma.array(procdata, mask=np.isnan(procdata)) 171 print('from nan processing {} and {}'.format(lb, ub))172 186 if nanfill < lb: 173 options.addfielddefault('cmap_set_under', ' k')187 options.addfielddefault('cmap_set_under', 'r') 174 188 elif nanfill > ub: 175 189 options.addfielddefault('cmap_set_over', 'k')
Note:
See TracChangeset
for help on using the changeset viewer.