def get_isobath(bbox, iso=-200, tfile=None, smoo=False): """ Finds an isobath on the etopo2 database and returns its lon, lat segments for plotting. Examples -------- >>> from oceans.datasets import etopo_subset, get_isobath >>> import matplotlib.pyplot as plt >>> bbox = [-43, -30, -22, -17] >>> segments = get_isobath(bbox=bbox, iso=-200, smoo=True) >>> lon, lat, bathy = etopo_subset(bbox=bbox, smoo=True) >>> fig, ax = plt.subplots() >>> cs = ax.pcolormesh(lon, lat, bathy) >>> for segment in segments: ... lines = ax.plot(segment[:, 0], segment[:, -1], 'k', linewidth=2) """ import matplotlib._contour as contour lon, lat, topo = etopo_subset(bbox, tfile=tfile, smoo=smoo) # Required args for QuadContourGenerator. mask, corner_mask, nchunk = None, True, 0 c = contour.QuadContourGenerator(lon, lat, topo, mask, corner_mask, nchunk) res = c.create_contour(iso) nseg = len(res) // 2 segments = res[:nseg] return segments
def test_internal_cpp_api_2(): import matplotlib._contour as _contour arr = [[0, 1], [2, 3]] qcg = _contour.QuadContourGenerator(arr, arr, arr, None, True, 0) with pytest.raises(ValueError, match=r'filled contour levels must be increasing'): qcg.create_filled_contour(1, 0)
def detect_contour(img, level): """Returns list of vertices of contours at a given level Arguments: img (array): the image array level (number): the level at which to create the contour Returns: (list of nx2 arrays): list of list of vertices of the different contours Note: The contour detection is based on matplotlib's QuadContourGenerator """ #parameter mask = None; corner_mask = True; nchunk = 0; #prepare image data z = ma.asarray(img, dtype=np.float64); ny, nx = z.shape; x, y = np.meshgrid(np.arange(nx), np.arange(ny)); #find contour contour_generator = _contour.QuadContourGenerator(x, y, z.filled(), mask, corner_mask, nchunk) vertices = contour_generator.create_contour(level); return vertices;
def get_contourset(X, Y, Z, level): contour_generator = cntr.QuadContourGenerator( X, Y, Z, None, mpl.rcParams["contour.corner_mask"], 0) allsegs = [contour_generator.create_contour(level)] flatseglist = [s for seg in allsegs for s in seg] points = np.concatenate(flatseglist, axis=0) x, y = points.T return x, y
def contour_lines(X, Y, Z, levels): # Preparation of values and the creating of contours is # adapted from MPL with some adjustments. X = np.asarray(X, dtype=np.float64) Y = np.asarray(Y, dtype=np.float64) Z = np.asarray(Z, dtype=np.float64) zmin, zmax = Z.min(), Z.max() mask = None corner_mask = False nchunk = 0 contour_generator = _contour.QuadContourGenerator(X, Y, Z, mask, corner_mask, nchunk) if isinstance(levels, int): levels = extended_breaks(n=levels)((zmin, zmax)) # The counter_generator gives us a list of vertices that # represent all the contour lines at that level. There # may be 0, 1 or more vertices at a level. Each one of # these we call a piece, and it represented as an nx2 array. # # We want x-y values that describe *all* the contour lines # in tidy format. Therefore each x-y vertex has a # corresponding level and piece id. segments = [] piece_ids = [] level_values = [] start_pid = 1 for level in levels: vertices = contour_generator.create_contour(level) for pid, piece in enumerate(vertices, start=start_pid): n = len(piece) segments.append(piece) piece_ids.append(np.repeat(pid, n)) level_values.append(np.repeat(level, n)) start_pid = pid + 1 # Collapse the info and make it fit for dataframe columns if segments: x, y = np.vstack(segments).T piece = np.hstack(piece_ids) level = np.hstack(level_values) else: x, y = [], [] piece = [] level = [] data = pd.DataFrame({ 'x': x, 'y': y, 'level': level, 'piece': piece, }) return data
def test_internal_cpp_api(): # Following github issue 8197. import matplotlib._contour as _contour with pytest.raises(TypeError) as excinfo: qcg = _contour.QuadContourGenerator() excinfo.match(r'function takes exactly 6 arguments \(0 given\)') with pytest.raises(ValueError) as excinfo: qcg = _contour.QuadContourGenerator(1, 2, 3, 4, 5, 6) excinfo.match(r'Expected 2-dimensional array, got 0') with pytest.raises(ValueError) as excinfo: qcg = _contour.QuadContourGenerator([[0]], [[0]], [[]], None, True, 0) excinfo.match(r'x, y and z must all be 2D arrays with the same dimensions') with pytest.raises(ValueError) as excinfo: qcg = _contour.QuadContourGenerator([[0]], [[0]], [[0]], None, True, 0) excinfo.match(r'x, y and z must all be at least 2x2 arrays') arr = [[0, 1], [2, 3]] with pytest.raises(ValueError) as excinfo: qcg = _contour.QuadContourGenerator(arr, arr, arr, [[0]], True, 0) excinfo.match(r'If mask is set it must be a 2D array with the same ' + r'dimensions as x.') qcg = _contour.QuadContourGenerator(arr, arr, arr, None, True, 0) with pytest.raises(ValueError) as excinfo: qcg.create_filled_contour(1, 0) excinfo.match(r'filled contour levels must be increasing')
def contourLines(self, stepCont=20, maxNodesPerWay=0, noZero=False, minCont=None, maxCont=None, rdpEpsilon=None, rdpMaxVertexDistance=None): """generates contour lines using matplotlib. <stepCont> is height difference of contiguous contour lines in meters <maxNodesPerWay>: the maximum number of nodes contained in each way <noZero>: if True, the 0 m contour line is discarded <minCont>: lower limit of the range to generate contour lines for <maxCont>: upper limit of the range to generate contour lines for <rdpEpsilon>: epsilon to use in RDP contour line simplification <rdpMaxVertexDistance>: maximal vertex distance in RDP simplification A list of elevations and a ContourObject is returned. """ def getContLimit(ele, step): """returns a proper value for the lower or upper limit to generate contour lines for. """ if ele%step == 0: return ele corrEle = ele + step - ele % step return corrEle minCont = minCont or getContLimit(self.minEle, stepCont) maxCont = maxCont or getContLimit(self.maxEle, stepCont) contourSet = [] if noZero: levels = [l for l in range(int(minCont), int(maxCont), stepCont) if l!=0] else: levels = range(int(minCont), int(maxCont), stepCont) x, y = numpy.meshgrid(self.xData, self.yData) # z data is a masked array filled with nan. z = numpy.ma.array(self.zData, mask=self.mask, fill_value=float("NaN"), keep_mask=True) if mplversion < "2.0.0": Contours = ContourObject(_cntr.Cntr(x, y, z.filled(), None), maxNodesPerWay, self.transform, self.polygon, rdpEpsilon, rdpMaxVertexDistance) else: corner_mask = True nchunk = 0 Contours = ContourObject( _contour.QuadContourGenerator(x, y, z.filled(), self.mask, corner_mask, nchunk), maxNodesPerWay, self.transform, self.polygon, rdpEpsilon, rdpMaxVertexDistance) return levels, Contours
def detect_contour(img, level): #parameter mask = None; corner_mask = True; nchunk = 0; #prepare image data z = ma.asarray(img, dtype=np.float64); ny, nx = z.shape; x, y = np.meshgrid(np.arange(nx), np.arange(ny)); #find contour contour_generator = _contour.QuadContourGenerator(x, y, z.filled(), mask, corner_mask, nchunk) vertices = contour_generator.create_contour(level); return vertices;
def __init__(self, x, y, z, formatter=numpy_formatter): """Initialize a :class:`QuadContourGenerator`, see class docstring.""" x = np.asarray(x, dtype=np.float64) y = np.asarray(y, dtype=np.float64) z = np.ma.asarray(z, dtype=np.float64) if x.shape != z.shape: raise TypeError( ("'x' and 'z' must be the same shape but 'x' has shape {:s} " "and 'z' has shape {:s}").format(str(x.shape), str(z.shape))) if y.shape != z.shape: raise TypeError( ("'y' and 'z' must be the same shape but 'y' has shape {:s} " "and 'z' has shape {:s}").format(str(y.shape), str(z.shape))) mask = z.mask if z.mask is not np.ma.nomask and z.mask.any() else None self._contour_generator = _contour.QuadContourGenerator( x, y, z.filled(), mask, True, 0) super().__init__(formatter)
def getcontour(filename, key, levels): data, lats, lons = extractdata(filename, key) data = data data, lons = shiftgrid(180., data, lons, start=False) data = scipy.ndimage.gaussian_filter(data, sigma=4, order=0) lons_m, lats_m = np.meshgrid(lons, lats) data = np.ma.asarray(data) data = np.ma.masked_invalid(data) _corner_mask = mpl.rcParams['contour.corner_mask'] _mask = np.ma.getmask(data) generator = _contour.QuadContourGenerator(lats_m, lons_m, data, _mask, _corner_mask, 0) contours = {} for level in levels: vertices = generator.create_contour(level) for i in range(len(vertices)): vertices[i] = vertices[i].tolist() contours[str(level)] = vertices return countours
def extract_contour_intervals(self, levels): """ Extract contour intervals from grid :param levels: list or array, contour line values :return: list with instances of :class:`MultiPolygonData` """ import numpy.ma as ma import matplotlib._contour as _contour values = ma.asarray(self.values) contour_engine = _contour.QuadContourGenerator(self.lons, self.lats, values.filled(), None, False, 0) contour_polygons = [] for lower_level, upper_level in zip(levels[:-1], levels[1:]): segs, path_codes = contour_engine.create_filled_contour(lower_level, upper_level) contour_mpg = MultiPolygonData([], []) for i in range(len(segs)): seg = segs[i] path_code = path_codes[i] seg = np.split(seg, np.where(path_code == 1)[0][1:]) for s, coords in enumerate(seg): if s == 0: lons, lats = coords[:,0], coords[:,1] interior_lons, interior_lats = [], [] else: if coords.shape[0] > 2: interior_lons.append(coords[:,0]) interior_lats.append(coords[:,1]) contour_pg = PolygonData(lons, lats, interior_lons=interior_lons, interior_lats=interior_lats, z=lower_level) contour_mpg.append(contour_pg) contour_polygons.append(contour_mpg) return contour_polygons
def calc_best_regions(motors, propellers, folder, conditions): """ Function to determine the best combination for every thrust and speed value over a region. Once the zones in which each combination is most efficient is known, a small list of the best combinations for a given thrust speed curve (for a plane) can be VERY quickly calculated. """ best_regions = [] combo_name_list = [] result_list = [] gen_props = pickle.load(open(folder + 'generation_properties.pk', "rb")) #Make sure the velocity and thrust ranges match, if they don't... Well it's probably not too bad but it's better to play safe. Umesh, Tmesh = np.meshgrid(gen_props['Urange'], gen_props['Trange']) Psurf_col = np.empty(np.shape(Umesh)) #This function runs very quickly, provided all the required power surfaces #have already been calculated. Don't run unless #Check to make sure all requested power surfaces have been calculated. for motor in motors: for propeller in propellers: combo_name = motor['name'] + ' - ' + propeller['name'] save_name = folder + motor['name'] + propeller['name'] + '.pk' if os.path.isfile(save_name): result = pickle.load(open(save_name, "rb")) combo_name_list.append(combo_name) result_list.append(result) Psurf_col = np.dstack( (Psurf_col, result['Psurf'])) #Collect power surface else: print('Combination missing') return #Get rid of the first entry of empties Psurf_col = Psurf_col[:, :, 1:] for i, combo_name in enumerate(combo_name_list): #Now we make a merged surface of ALL of the power surfaces EXCEPT #the one for the current combination Psurf_min = np.nanmin(np.delete(Psurf_col, i, axis=2), axis=2) # print(np.shape(Psurfs)) #And here we find the difference between this merged surface and the current power surface Diffsurf = Psurf_col[:, :, i] - Psurf_min #The next step is to find the 0 contour of this difference surface, this equates #to the intersetctions of the surfaces. zmin = np.nanmin(Diffsurf) if zmin == 0: print(Diffsurf) if zmin < 0: levels = [np.nanmin(Diffsurf), 0] #Now we do some serious black magic to get the filled contour regions WITHOUT the plotting overhead mask = None #Don't even ask corner_mask = rcParams['contour.corner_mask'] #Seriously don't ask Diffsurf = np.ma.masked_invalid( Diffsurf, copy=False) #Get a masked array for the z values #Now we use an undocumented contour generating back-end function. May easily change in future #versions, watch out. contf = contour_func.QuadContourGenerator(Umesh, Tmesh, Diffsurf.filled(), mask, corner_mask, 0) #It returns a list of lists vertices and path codes (used to define the vertex type) vertices, kinds = contf.create_filled_contour(levels[0], levels[1]) #Turn each list in the list into a path, then put the paths in another list paths = [ path.Path(seg, codes=kind) for seg, kind in zip(vertices, kinds) ] region = {'combo_name': combo_name, 'region': paths} best_regions.append(region) else: continue #TODO: Get bounds of each region, and use these bounds to get an estimation #of possible enclosing regions for each point in order to only have to #check if a given point is inside 3 or 4 regions instead of all of them return best_regions
def test_internal_cpp_api(args, cls, message): # Github issue 8197. import matplotlib._contour as _contour with pytest.raises(cls, match=re.escape(message)): _contour.QuadContourGenerator(*args)
def rho2rz(self, rho_in, t_in=None, coord_in='rho_pol', all_lines=False): """Get R, Z coordinates of a flux surfaces contours Input ---------- t_in : float or 1darray time rho_in : 1darray,float rho coordinates of the searched flux surfaces coord_in: str mapped coordinates - rho_pol or rho_tor all_lines: bool: True - return all countours , False - return longest contour Output ------- rho : array of lists of arrays [npoinst,2] list of times containg list of surfaces for different rho and every surface is decribed by 2d array [R,Z] """ if not self.eq_open: return if t_in is None: t_in = self.t_eq tarr = np.atleast_1d(t_in) rhoin = np.atleast_1d(rho_in) self._read_pfm() self._read_scalars() rho_in = self.rho2rho(rhoin, t_in=t_in, \ coord_in=coord_in, coord_out='Psi', extrapolate=True ) try: import matplotlib._cntr as cntr except: #slower option import matplotlib._contour as _contour nr = len(self.Rmesh) nz = len(self.Zmesh) R, Z = np.meshgrid(self.Rmesh, self.Zmesh) Rsurf = np.empty(len(tarr), dtype='object') zsurf = np.empty(len(tarr), dtype='object') unique_idx, idx = self._get_nearest_index(tarr) for i in unique_idx: jt = np.where(idx == i)[0] Flux = rho_in[jt[0]] # matplotlib's contour creation try: c = cntr.Cntr(R, Z, self.pfm[i].T) except: #slower option gen = _contour.QuadContourGenerator(R, Z, self.pfm[i].T, np.bool_(Z * 0), False, 0) Rs_t = [] zs_t = [] for jfl, fl in enumerate(Flux): try: nlist = c.trace(level0=fl, level1=fl, nchunk=0) nlist = nlist[:len(nlist) / 2] except: #slower option nlist = gen.create_contour(fl) j_ctrs = len(nlist) if j_ctrs == 0: if fl == self.psi0[i]: Rs_t.append(np.atleast_1d(self.ssq['Rmag'][i])) zs_t.append(np.atleast_1d(self.ssq['Zmag'][i])) else: Rs_t.append(np.zeros(1)) zs_t.append(np.zeros(1)) continue elif all_lines: # for open field lines line = np.vstack([ np.vstack(((np.nan, ) * 2, l)) for l in nlist[:j_ctrs] ])[1:] else: #longest filed line line = [] for l in nlist[:j_ctrs]: if len(l) > len(line): line = l R_surf, z_surf = list(zip(*line)) R_surf = np.array(R_surf, dtype=np.float32) z_surf = np.array(z_surf, dtype=np.float32) if not all_lines: ind = (z_surf >= self.ssq['Zunt'][i]) if len(ind) > 1: R_surf = R_surf[ind] z_surf = z_surf[ind] Rs_t.append(R_surf) zs_t.append(z_surf) for j in jt: Rsurf[j] = Rs_t zsurf[j] = zs_t return Rsurf, zsurf
def plot_kde( density, lower, upper, density_q, xmin, xmax, ymin, ymax, gridsize, values, values2, rug, label, # pylint: disable=unused-argument quantiles, rotated, contour, fill_last, figsize, textsize, # pylint: disable=unused-argument plot_kwargs, fill_kwargs, rug_kwargs, contour_kwargs, contourf_kwargs, pcolormesh_kwargs, is_circular, # pylint: disable=unused-argument ax, legend, # pylint: disable=unused-argument backend_kwargs, show, return_glyph, ): """Bokeh kde plot.""" if backend_kwargs is None: backend_kwargs = {} backend_kwargs = { **backend_kwarg_defaults(), **backend_kwargs, } figsize, *_ = _scale_fig_size(figsize, textsize) if ax is None: ax = create_axes_grid( 1, figsize=figsize, squeeze=True, backend_kwargs=backend_kwargs, ) glyphs = [] if values2 is None: if plot_kwargs is None: plot_kwargs = {} plot_kwargs.setdefault( "line_color", mpl_rcParams["axes.prop_cycle"].by_key()["color"][0]) if fill_kwargs is None: fill_kwargs = {} fill_kwargs.setdefault( "fill_color", mpl_rcParams["axes.prop_cycle"].by_key()["color"][0]) if rug: if rug_kwargs is None: rug_kwargs = {} rug_kwargs = rug_kwargs.copy() if "cds" in rug_kwargs: cds_rug = rug_kwargs.pop("cds") rug_varname = rug_kwargs.pop("y", "y") else: rug_varname = "y" cds_rug = ColumnDataSource({rug_varname: np.asarray(values)}) rug_kwargs.setdefault("size", 8) rug_kwargs.setdefault("line_color", plot_kwargs["line_color"]) rug_kwargs.setdefault("line_width", 1) rug_kwargs.setdefault("line_alpha", 0.35) if not rotated: rug_kwargs.setdefault("angle", np.pi / 2) if isinstance(cds_rug, dict): for _cds_rug in cds_rug.values(): if not rotated: glyph = Dash(x=rug_varname, y=0.0, **rug_kwargs) else: glyph = Dash(x=0.0, y=rug_varname, **rug_kwargs) ax.add_glyph(_cds_rug, glyph) else: if not rotated: glyph = Dash(x=rug_varname, y=0.0, **rug_kwargs) else: glyph = Dash(x=0.0, y=rug_varname, **rug_kwargs) ax.add_glyph(cds_rug, glyph) glyphs.append(glyph) x = np.linspace(lower, upper, len(density)) if quantiles is not None: fill_kwargs.setdefault("fill_alpha", 0.75) fill_kwargs.setdefault("line_color", None) quantiles = sorted(np.clip(quantiles, 0, 1)) if quantiles[0] != 0: quantiles = [0] + quantiles if quantiles[-1] != 1: quantiles = quantiles + [1] for quant_0, quant_1 in zip(quantiles[:-1], quantiles[1:]): idx = (density_q > quant_0) & (density_q < quant_1) if idx.sum(): patch_x = np.concatenate( (x[idx], [x[idx][-1]], x[idx][::-1], [x[idx][0]])) patch_y = np.concatenate( (np.zeros_like(density[idx]), [density[idx][-1]], density[idx][::-1], [0])) if not rotated: patch = ax.patch(patch_x, patch_y, **fill_kwargs) else: patch = ax.patch(patch_y, patch_x, **fill_kwargs) glyphs.append(patch) else: if fill_kwargs.get("fill_alpha", False): patch_x = np.concatenate((x, [x[-1]], x[::-1], [x[0]])) patch_y = np.concatenate((np.zeros_like(density), [density[-1]], density[::-1], [0])) if not rotated: patch = ax.patch(patch_x, patch_y, **fill_kwargs) else: patch = ax.patch(patch_y, patch_x, **fill_kwargs) glyphs.append(patch) if not rotated: line = ax.line(x, density, **plot_kwargs) else: line = ax.line(density, x, **plot_kwargs) glyphs.append(line) else: if contour_kwargs is None: contour_kwargs = {} if contourf_kwargs is None: contourf_kwargs = {} if pcolormesh_kwargs is None: pcolormesh_kwargs = {} g_s = complex(gridsize[0]) x_x, y_y = np.mgrid[xmin:xmax:g_s, ymin:ymax:g_s] if contour: scaled_density, *scaled_density_args = _scale_axis(density) contour_generator = _contour.QuadContourGenerator( x_x, y_y, scaled_density, None, True, 0) if "levels" in contour_kwargs: levels = contour_kwargs.get("levels") elif "levels" in contourf_kwargs: levels = contourf_kwargs.get("levels") else: levels = 11 if isinstance(levels, Integral): levels_scaled = np.linspace(0, 1, levels) levels = _rescale_axis(levels_scaled, scaled_density_args) else: levels_scaled_nonclip = _scale_axis(np.asarray(levels), scaled_density_args) levels_scaled = np.clip(levels_scaled_nonclip, 0, 1) cmap = contourf_kwargs.pop("cmap", "viridis") if isinstance(cmap, str): cmap = get_cmap(cmap) if isinstance(cmap, Callable): colors = [ rgb2hex(item) for item in cmap(np.linspace(0, 1, len(levels_scaled) + 1)) ] else: colors = cmap contour_kwargs.update(contourf_kwargs) contour_kwargs.setdefault("line_color", "black") contour_kwargs.setdefault("line_alpha", 0.25) contour_kwargs.setdefault("fill_alpha", 1) for i, (level, level_upper, color) in enumerate( zip(levels_scaled[:-1], levels_scaled[1:], colors[1:])): if not fill_last and (i == 0): continue vertices, _ = contour_generator.create_filled_contour( level, level_upper) for seg in vertices: patch = ax.patch(*seg.T, fill_color=color, **contour_kwargs) glyphs.append(patch) if fill_last: ax.background_fill_color = colors[0] ax.xgrid.grid_line_color = None ax.ygrid.grid_line_color = None ax.x_range = Range1d(xmin, xmax) ax.y_range = Range1d(ymin, ymax) else: cmap = pcolormesh_kwargs.pop("cmap", "viridis") if isinstance(cmap, str): cmap = get_cmap(cmap) if isinstance(cmap, Callable): colors = [ rgb2hex(item) for item in cmap(np.linspace(0, 1, 256)) ] else: colors = cmap image = ax.image(image=[density.T], x=xmin, y=ymin, dw=(xmax - xmin) / density.shape[0], dh=(ymax - ymin) / density.shape[1], palette=colors, **pcolormesh_kwargs) glyphs.append(image) ax.x_range.range_padding = ax.y_range.range_padding = 0 show_layout(ax, show) if return_glyph: return ax, glyphs return ax
def nullcline(x, y, z): c = _contour.QuadContourGenerator(x, y, z, None, True, 0) segments = c.create_contour(0.0) return segments
import matplotlib as mpl import matplotlib._contour as _contour _mask = None; _corner_mask = None; _corner_mask = mpl.rcParams['contour.corner_mask'] nchunk = 0; z = ma.asarray(imgs, dtype=np.float64); Ny, Nx = z.shape; x, y= np.meshgrid(np.arange(Nx), np.arange(Ny)); contour_generator = _contour.QuadContourGenerator(x, y, z.filled(), _mask, _corner_mask, nchunk) vertices = contour_generator.create_contour(level - 20) import matplotlib.pyplot as plt plt.figure(100); plt.clf(); plt.imshow(imgs); for j in range(len(vertices)): plt.scatter(vertices[j][:,0], vertices[j][:,1])
import scipy.io as sio import numpy as np import matplotlib._contour as _contour import matplotlib as mpl from basemap_func import shiftgrid import json f = sio.netcdf_file( "icon_global_icosahedral_single-level_2018111000_000_T_2M.nc") data = f.variables['2t'] data = data[0, 0, :, :] - 273.15 lons = np.array(f.variables['lon'][:]) lats = np.array(f.variables['lat'][:]) f.close() data, lons = shiftgrid(180., data, lons, start=False) lons_m, lats_m = np.meshgrid(lons, lats) data = np.ma.asarray(data) data = np.ma.masked_invalid(data) _corner_mask = mpl.rcParams['contour.corner_mask'] _mask = np.ma.getmask(data) generator = _contour.QuadContourGenerator(lats_m, lons_m, data, _mask, _corner_mask, 0) vertices = generator.create_contour(25) for i in range(len(vertices)): vertices[i] = vertices[i].tolist() with open('contour.json', 'w') as outfile: json.dump(vertices, outfile)
def _plot_kde_bokeh( density, lower, upper, density_q, xmin, xmax, ymin, ymax, gridsize, values, values2=None, rug=False, label=None, quantiles=None, rotated=False, contour=True, fill_last=True, plot_kwargs=None, fill_kwargs=None, rug_kwargs=None, contour_kwargs=None, contourf_kwargs=None, pcolormesh_kwargs=None, ax=None, legend=True, show=True, ): if ax is None: tools = rcParams["plot.bokeh.tools"] output_backend = rcParams["plot.bokeh.output_backend"] ax = bkp.figure( width=rcParams["plot.bokeh.figure.width"], height=rcParams["plot.bokeh.figure.height"], output_backend=output_backend, tools=tools, ) if legend and label is not None: plot_kwargs["legend_label"] = label if values2 is None: if plot_kwargs is None: plot_kwargs = {} plot_kwargs.setdefault( "line_color", mpl_rcParams["axes.prop_cycle"].by_key()["color"][0]) if fill_kwargs is None: fill_kwargs = {} fill_kwargs.setdefault( "fill_color", mpl_rcParams["axes.prop_cycle"].by_key()["color"][0]) if rug: if rug_kwargs is None: rug_kwargs = {} rug_kwargs = rug_kwargs.copy() if "cds" in rug_kwargs: cds_rug = rug_kwargs.pop("cds") rug_varname = rug_kwargs.pop("y", "y") else: rug_varname = "y" cds_rug = ColumnDataSource({rug_varname: np.asarray(values)}) rug_kwargs.setdefault("size", 8) rug_kwargs.setdefault("line_color", plot_kwargs["line_color"]) rug_kwargs.setdefault("line_width", 1) rug_kwargs.setdefault("line_alpha", 0.35) if not rotated: rug_kwargs.setdefault("angle", np.pi / 2) if isinstance(cds_rug, dict): for _cds_rug in cds_rug.values(): if not rotated: glyph = Dash(x=rug_varname, y=0.0, **rug_kwargs) else: glyph = Dash(x=0.0, y=rug_varname, **rug_kwargs) ax.add_glyph(_cds_rug, glyph) else: if not rotated: glyph = Dash(x=rug_varname, y=0.0, **rug_kwargs) else: glyph = Dash(x=0.0, y=rug_varname, **rug_kwargs) ax.add_glyph(cds_rug, glyph) x = np.linspace(lower, upper, len(density)) if quantiles is not None: fill_kwargs.setdefault("fill_alpha", 0.75) fill_kwargs.setdefault("line_color", None) quantiles = sorted(np.clip(quantiles, 0, 1)) if quantiles[0] != 0: quantiles = [0] + quantiles if quantiles[-1] != 1: quantiles = quantiles + [1] for quant_0, quant_1 in zip(quantiles[:-1], quantiles[1:]): idx = (density_q > quant_0) & (density_q < quant_1) if idx.sum(): patch_x = np.concatenate( (x[idx], [x[idx][-1]], x[idx][::-1], [x[idx][0]])) patch_y = np.concatenate( (np.zeros_like(density[idx]), [density[idx][-1]], density[idx][::-1], [0])) if not rotated: ax.patch(patch_x, patch_y, **fill_kwargs) else: ax.patch(patch_y, patch_x, **fill_kwargs) else: if fill_kwargs.get("fill_alpha", False): patch_x = np.concatenate((x, [x[-1]], x[::-1], [x[0]])) patch_y = np.concatenate((np.zeros_like(density), [density[-1]], density[::-1], [0])) if not rotated: ax.patch(patch_x, patch_y, **fill_kwargs) else: ax.patch(patch_y, patch_x, **fill_kwargs) if not rotated: ax.line(x, density, **plot_kwargs) else: ax.line(density, x, **plot_kwargs) else: if contour_kwargs is None: contour_kwargs = {} if contourf_kwargs is None: contourf_kwargs = {} if pcolormesh_kwargs is None: pcolormesh_kwargs = {} g_s = complex(gridsize[0]) x_x, y_y = np.mgrid[xmin:xmax:g_s, ymin:ymax:g_s] if contour: scaled_density, *scaled_density_args = _scale_axis(density) contour_generator = _contour.QuadContourGenerator( x_x, y_y, scaled_density, None, True, 0) if "levels" in contour_kwargs: levels = contour_kwargs.get("levels") elif "levels" in contourf_kwargs: levels = contourf_kwargs.get("levels") else: levels = 11 if isinstance(levels, Integral): levels_scaled = np.linspace(0, 1, levels) levels = _rescale_axis(levels_scaled, scaled_density_args) else: levels_scaled_nonclip = _scale_axis(np.asarray(levels), scaled_density_args) levels_scaled = np.clip(levels_scaled_nonclip, 0, 1) cmap = contourf_kwargs.pop("cmap", "viridis") if isinstance(cmap, str): cmap = get_cmap(cmap) if isinstance(cmap, Callable): colors = [ rgb2hex(item) for item in cmap(np.linspace(0, 1, len(levels_scaled) + 1)) ] else: colors = cmap contour_kwargs.update(contourf_kwargs) contour_kwargs.setdefault("line_color", "black") contour_kwargs.setdefault("line_alpha", 0.25) contour_kwargs.setdefault("fill_alpha", 1) for i, (level, level_upper, color) in enumerate( zip(levels_scaled[:-1], levels_scaled[1:], colors[1:])): if not fill_last and (i == 0): continue vertices, _ = contour_generator.create_filled_contour( level, level_upper) for seg in vertices: ax.patch(*seg.T, fill_color=color, **contour_kwargs) if fill_last: ax.background_fill_color = colors[0] ax.xgrid.grid_line_color = None ax.ygrid.grid_line_color = None ax.x_range = Range1d(xmin, xmax) ax.y_range = Range1d(ymin, ymax) else: cmap = pcolormesh_kwargs.pop("cmap", "viridis") if isinstance(cmap, str): cmap = get_cmap(cmap) if isinstance(cmap, Callable): colors = [ rgb2hex(item) for item in cmap(np.linspace(0, 1, 256)) ] else: colors = cmap ax.image(image=[density.T], x=xmin, y=ymin, dw=(xmax - xmin) / density.shape[0], dh=(ymax - ymin) / density.shape[1], palette=colors, **pcolormesh_kwargs) ax.x_range.range_padding = ax.y_range.range_padding = 0 if show: bkp.show(ax, toolbar_location="above") return ax
def contourLines(self, stepCont=20, maxNodesPerWay=0, noZero=False, minCont=None, maxCont=None, rdpEpsilon=None, rdpMaxVertexDistance=None, scale=1, smooth=0): """generates contour lines using matplotlib. <stepCont> is height difference of contiguous contour lines in meters <maxNodesPerWay>: the maximum number of nodes contained in each way <noZero>: if True, the 0 m contour line is discarded <minCont>: lower limit of the range to generate contour lines for <maxCont>: upper limit of the range to generate contour lines for <rdpEpsilon>: epsilon to use in RDP contour line simplification <rdpMaxVertexDistance>: maximal vertex distance in RDP simplification A list of elevations and a ContourObject is returned. """ def getContLimit(ele, step): """returns a proper value for the lower or upper limit to generate contour lines for. """ if ele % step == 0: return ele corrEle = ele + step - ele % step return corrEle minCont = minCont or getContLimit(self.minEle, stepCont) maxCont = maxCont or getContLimit(self.maxEle, stepCont) contourSet = [] if noZero: levels = [ l for l in range(int(minCont), int(maxCont), stepCont) if l != 0 ] else: levels = range(int(minCont), int(maxCont), stepCont) x, y = numpy.meshgrid(self.xData, self.yData) # z data is a masked array filled with nan. z = numpy.ma.array(self.zData, mask=self.mask, fill_value=float("NaN"), keep_mask=True) #Get smoother contours by a) interpolating SRTM data (with scale factor scale), # Then smooth the data using a Gaussian filter. #scale=4 x2 = numpy.linspace(self.xData[0], self.xData[-1], len(self.xData) * scale) y2 = numpy.linspace(self.yData[0], self.yData[-1], len(self.yData) * scale) xnew, ynew = numpy.meshgrid(x2, y2) #znew = f(xnew, ynew) import scipy.ndimage from scipy.ndimage.filters import gaussian_filter sm = int(smooth * scale) #znew = scipy.ndimage.grey_dilation(scipy.ndimage.grey_erosion(scipy.ndimage.zoom(z, scale),size=(sm,sm)), size=(sm,sm)) #sigma = 4.0 # this depends on how noisy your data is, play with it! #znew = gaussian_filter(znew, sigma) znew = gaussian_filter(scipy.ndimage.zoom(z, scale), sm) if mplversion < "2.0.0": Contours = ContourObject(_cntr.Cntr(xnew, ynew, znew, None), maxNodesPerWay, self.transform, self.polygon, rdpEpsilon, rdpMaxVertexDistance) else: corner_mask = True nchunk = 0 Contours = ContourObject( _contour.QuadContourGenerator(xnew, ynew, znew, self.mask, corner_mask, nchunk), #_contour.QuadContourGenerator(x, y, z.filled(), self.mask, corner_mask, nchunk), maxNodesPerWay, self.transform, self.polygon, rdpEpsilon, rdpMaxVertexDistance) return levels, Contours