def main(): fig, ax = plt.subplots(3, 2, figsize=(7, 10)) fig.tight_layout() if 1: # Same terrain and data. data = make_test_data('circles', noise_factor=0.05) * 2 - 7 terrain = data else: # Different terrain and data. Matplotlib hill shading can only show the data. data = make_test_data('hills') * -1 terrain = make_test_data('circles', noise_factor=0.05) * 2 assert terrain.shape == data.shape, "{} != {}".format(terrain.shape, data.shape) print("data range: {} {}".format(np.min(data), np.max(data))) if len(sys.argv) > 1: cmap_name = sys.argv[1] else: #cmap_name = 'copper' # from http://matplotlib.org/examples/pylab_examples/shading_example.html?highlight=codex%20shade #cmap_name = 'gist_earth' # works reasonably fine with all of them cmap_name = 'bwr' # shows that mpl & pegtop don't work when there is no increasing intensity #cmap_name = 'cubehelix' # shows that HSV blending does not work were color is black #cmap_name = 'rainbow' # shows that mpl & pegtop don't work when there is no increasing intensity #cmap_name = 'Paired_r' # is nice to inspect when the data is different from the terrain print ("Using colormap: {!r}".format(cmap_name)) cmap = plt.cm.get_cmap(cmap_name) cmap.set_bad('cyan') cmap.set_over('cyan') cmap.set_under('cyan') abs_max = np.max(np.abs(data)) # force color bar to be symmetrical. norm = mpl.colors.Normalize(vmin=-abs_max, vmax=abs_max) #norm = mpl.colors.Normalize(vmin=-2, vmax=3) draw(ax[0, 0], cmap=cmap, norm=norm, title='No shading', image_data = data) draw(ax[0, 1], cmap=plt.cm.gray, title='Matplotlib intensity', image_data = mpl_surface_intensity(terrain)) ls = LightSource(azdeg=DEF_AZIMUTH, altdeg=DEF_ELEVATION) draw(ax[1, 0], cmap=cmap, norm=norm, title='Matplotlib hill shading', image_data = ls.shade(data, cmap=cmap, norm=norm)) draw(ax[1, 1], cmap=cmap, norm=norm, title='Pegtop blending', image_data = mpl_hill_shade(data, terrain=terrain, cmap=cmap, norm=norm, blend_function=pegtop_blending)) draw(ax[2, 0], cmap=cmap, norm=norm, title='RGB blending', image_data = mpl_hill_shade(data, terrain=terrain, cmap=cmap, norm=norm, blend_function=rgb_blending)) draw(ax[2, 1], cmap=cmap, norm=norm, title='HSV blending', image_data = mpl_hill_shade(data, terrain=terrain, cmap=cmap, norm=norm, blend_function=hsv_blending)) plt.show()
def test_light_source_shading_color_range(): # see also #http://matplotlib.org/examples/pylab_examples/shading_example.html from matplotlib.colors import LightSource from matplotlib.colors import Normalize refinput = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]) norm = Normalize(vmin=0, vmax=50) ls = LightSource(azdeg=0, altdeg=65) testoutput = ls.shade(refinput, plt.cm.jet, norm=norm) refoutput = np.array([ [[0., 0., 0.58912656, 1.], [0., 0., 0.67825312, 1.], [0., 0., 0.76737968, 1.], [0., 0., 0.85650624, 1.]], [[0., 0., 0.9456328, 1.], [0., 0., 1., 1.], [0., 0.04901961, 1., 1.], [0., 0.12745098, 1., 1.]], [[0., 0.22156863, 1., 1.], [0., 0.3, 1., 1.], [0., 0.37843137, 1., 1.], [0., 0.45686275, 1., 1.]] ]) assert_array_almost_equal(refoutput, testoutput)
def SurfPlot(data): from mpl_toolkits.mplot3d import Axes3D from matplotlib import cbook from matplotlib import cm from matplotlib.colors import LightSource import matplotlib.pyplot as plt import numpy as np ncols, nrows = data.shape if ncols * nrows > 20000: print 'Warning, surface plotting things of this size is slow...' z = data x = np.linspace(0, ncols, ncols) y = np.linspace(0, nrows, nrows) x, y = np.meshgrid(x, y) region = np.s_[0:min(ncols,nrows), 0:min(ncols,nrows)] x, y, z = x[region], y[region], z[region] fig, ax = plt.subplots(subplot_kw=dict(projection='3d'), figsize=(10,10)) ls = LightSource(270, 45) # To use a custom hillshading mode, override the built-in shading and pass # in the rgb colors of the shaded surface calculated from "shade". rgb = ls.shade(z, cmap=cm.CMRmap, vert_exag=0.01, blend_mode='soft') surf = ax.plot_surface(x, y, z, rstride=1, cstride=1, facecolors=rgb, linewidth=0, antialiased=True, shade=False) plt.show()
def plot_shaded(self, cmap=plt.cm.terrain, lightsource_kwargs=None, *args, **kwargs): if lightsource_kwargs is None: lightsource_kwargs = {'azdeg':225, 'altdeg':5} extent = [self.x.min(), self.x.max(), self.y.min(), self.y.max()] arr = self.z.copy() nan_mask = np.isnan(arr) arr_min = arr[~nan_mask].min() if nan_mask.any(): arr[nan_mask] = max(arr_min-10, 0) ls = LightSource(**lightsource_kwargs) shaded = ls.shade(arr, cmap=cmap) fig = plt.figure() ax = fig.add_subplot(111) im = ax.imshow(shaded, cmap=cmap, extent=extent, *args, **kwargs) plt.colorbar(im) ax.get_xaxis().get_major_formatter().set_useOffset(False) ax.get_yaxis().get_major_formatter().set_useOffset(False) plt.show()
def background_map(self, ax): llcrnrlat, urcrnrlat, llcrnrlon, urcrnrlon, lat_ts = (31, 44, -126, -113, 37.5) m = Basemap(projection='merc', llcrnrlat=llcrnrlat, urcrnrlat=urcrnrlat, llcrnrlon=llcrnrlon, urcrnrlon=urcrnrlon, lat_ts=lat_ts, resolution='i', ax=ax) m.drawmapboundary(fill_color='lightblue', zorder=0) m.fillcontinents(zorder=0) etopofn = '/home/behry/uni/data/etopo1_central_europe_gmt.grd' etopodata = Dataset(etopofn, 'r') z = etopodata.variables['z'][:] x_range = etopodata.variables['x_range'][:] y_range = etopodata.variables['y_range'][:] spc = etopodata.variables['spacing'][:] lats = np.arange(y_range[0], y_range[1], spc[1]) lons = np.arange(x_range[0], x_range[1], spc[0]) topoin = z.reshape(lats.size, lons.size, order='C') # transform to nx x ny regularly spaced 5km native projection grid nx = int((m.xmax - m.xmin) / 5000.) + 1; ny = int((m.ymax - m.ymin) / 5000.) + 1 topodat, x, y = m.transform_scalar(np.flipud(topoin), lons, lats, nx, ny, returnxy=True) ls = LightSource(azdeg=300, altdeg=15, hsv_min_sat=0.2, hsv_max_sat=0.3, hsv_min_val=0.2, hsv_max_val=0.3) # shade data, creating an rgb array. rgb = ls.shade(np.ma.masked_less(topodat / 1000.0, 0.0), cm.gist_gray_r) m.imshow(rgb) m.drawmeridians(np.arange(6, 12, 2), labels=[0, 0, 0, 1], color='white', linewidth=0.5, zorder=0) m.drawparallels(np.arange(44, 50, 2), labels=[1, 0, 0, 0], color='white', linewidth=0.5, zorder=0) m.drawcoastlines(zorder=1) m.drawcountries(linewidth=1.5, zorder=1) m.drawstates() m.drawrivers(color='lightblue', zorder=1) return m
def apply(self): from mpl_toolkits.basemap import shiftgrid, cm common.ShowQuestion display = self.VpyartDisplay.value if (isinstance(display, pyart.graph.RadarMapDisplay) or isinstance(display, pyart.graph.GridMapDisplay)): pass elif (isinstance(display, pyart.graph.RadarDisplay) or isinstance(display, pyart.graph.AirborneRadarDisplay)): common.ShowWarning( "Topography require a MapDisplay, be sure to " "check the 'use MapDisplay' box in the 'Display Options' Menu") return else: common.ShowWarning( "Need a pyart display instance, be sure to " "link this components (%s), to a radar or grid display" % self.name) return filename = str(self.lineEdit.text()) if filename != self.current_open: if filename.startswith("http"): resp = common.ShowQuestion( "Loading a file from the internet may take long." + " Are you sure you want to continue?") if resp != QtWidgets.QMessageBox.Ok: return self.etopodata = Dataset(filename) self.current_open = filename topoin = np.maximum(0, self.etopodata.variables['ROSE'][:]) lons = self.etopodata.variables['ETOPO05_X'][:] lats = self.etopodata.variables['ETOPO05_Y'][:] # shift data so lons go from -180 to 180 instead of 20 to 380. topoin, lons = shiftgrid(180., topoin, lons, start=False) # plot topography/bathymetry as an image. # create the figure and axes instances. # setup of basemap ('lcc' = lambert conformal conic). # use major and minor sphere radii from WGS84 ellipsoid. m = self.VpyartDisplay.value.basemap # transform to nx x ny regularly spaced 5km native projection grid nx = int((m.xmax - m.xmin)/500.) + 1 ny = int((m.ymax - m.ymin)/500.) + 1 topodat = m.transform_scalar(topoin, lons, lats, nx, ny) # plot image over map with imshow. # draw coastlines and political boundaries. ls = LightSource(azdeg=90, altdeg=20) # convert data to rgb array including shading from light source. # (must specify color map) rgb = ls.shade(topodat, cm.GMT_relief) im = m.imshow(rgb) self.VpyartDisplay.update(strong=False)
def draw_figure(self): ls = LightSource(azdeg=315, altdeg=45) self.surf = self.data # try to plot the whole array try: blended_surface = ls.shade(self.surf, cmap=self.colormap, vert_exag=5, blend_mode=b"overlay", vmin=np.nanmin(self.surf), vmax=np.nanmax(self.surf)) # too big, two attempts for sub-sampling except MemoryError: rows = self.data.shape[0] cols = self.data.shape[1] # 1st attempt: <= 1024x1024 try: max_elements = 1024 row_stride = rows // max_elements + 1 col_stride = cols // max_elements + 1 self.surf = self.data[::row_stride, ::col_stride] blended_surface = ls.shade(self.surf, cmap=self.colormap, vert_exag=5, blend_mode=b"overlay", vmin=np.nanmin(self.surf), vmax=np.nanmax(self.surf)) except MemoryError: # 2st attempt: <= 512x512 max_elements = 512 row_stride = rows // max_elements + 1 col_stride = cols // max_elements + 1 self.surf = self.data[::row_stride, ::col_stride] blended_surface = ls.shade(self.surf, cmap=self.colormap, vert_exag=5, blend_mode=b"overlay", vmin=np.nanmin(self.surf), vmax=np.nanmax(self.surf)) log.debug("too big: %s x %s > subsampled to %s x %s" % (self.data.shape[0], self.data.shape[1], self.surf.shape[0], self.surf.shape[1])) self.axes.coastlines(resolution='50m', color='gray', linewidth=1) img = self.axes.imshow(blended_surface, origin='lower', cmap=self.colormap, extent=self.geo_extent, transform=ccrs.PlateCarree()) img.set_clim(vmin=np.nanmin(self.surf), vmax=np.nanmax(self.surf)) # add gridlines with labels only on the left and on the bottom grl = self.axes.gridlines(crs=ccrs.PlateCarree(), color='gray', draw_labels=True) grl.xformatter = LONGITUDE_FORMATTER grl.yformatter = LATITUDE_FORMATTER grl.xlabel_style = {'size': 8} grl.ylabel_style = {'size': 8} grl.ylabels_right = False grl.xlabels_top = False if self.cb: self.cb.on_mappable_changed(img) else: self.cb = plt.colorbar(img, ax=self.axes) self.cb.ax.tick_params(labelsize=8)
def plotRainbow(self): self.setUp() ls = LightSource(270, 45) # To use a custom hillshading mode, override the built-in shading and pass # in the rgb colors of the shaded surface calculated from "shade". rgb = ls.shade(self.Z, cmap=cm.gist_earth, vert_exag=0.1, blend_mode='soft') self.ax.plot_surface(self.X, self.Y, self.Z, facecolors=rgb) self.setLabels() plt.show()
def getTopoRGB(topogrid): topotmp = topogrid.getData().copy() # make a masked array topotmp = np.ma.array(topotmp) topodat = np.ma.masked_where(np.isnan(topotmp), topotmp) cy = topogrid.geodict["ymin"] + (topogrid.geodict["ymax"] - topogrid.geodict["ymin"]) / 2.0 # flag the regions where topography is less than 0 (we'll color this ocean later) i = np.where(topodat == SEA_LEVEL) # do shaded relief stuff # keys are latitude values # values are multiplication factor zdict = { 0: 0.00000898, 10: 0.00000912, 20: 0.00000956, 30: 0.00001036, 40: 0.00001171, 50: 0.00001395, 60: 0.00001792, 70: 0.00002619, 80: 0.00005156, } # find the mean latitude of the map we're making, and use that to come up with a zfactor mlat = abs(int(round(cy / 10) * 10)) zfactor = zdict[mlat] ls = LightSource(azdeg=AZDEFAULT, altdeg=ALTDEFAULT) # draw the ocean in light blue water_color = [0.47, 0.60, 0.81] palette1 = copy.deepcopy(cm.binary) # draw the light shaded-topography rgbdata = topodat * zfactor # apply the latitude specific zfactor correction rgb = ls.shade(rgbdata, cmap=palette1) # apply the light shading to our corrected topography # this is an rgb data set now, so masking the pixels won't work, but explicitly setting all of the # "bad" pixels to our water color will red = rgb[:, :, 0] green = rgb[:, :, 1] blue = rgb[:, :, 2] red[i] = water_color[0] green[i] = water_color[1] blue[i] = water_color[2] rgb[:, :, 0] = red rgb[:, :, 1] = green rgb[:, :, 2] = blue rgb = np.flipud(rgb) return (rgb, palette1)
def shade_other_data(): """Demonstrates displaying different variables through shade and color.""" y, x = np.mgrid[-4:2:200j, -4:2:200j] z1 = np.sin(x**2) # Data to hillshade z2 = np.cos(x**2 + y**2) # Data to color norm = Normalize(z2.min(), z2.max()) cmap = plt.cm.RdBu ls = LightSource(315, 45) rgb = ls.shade_rgb(cmap(norm(z2)), z1) fig, ax = plt.subplots() ax.imshow(rgb) ax.set_title('Shade by one variable, color by another', size='x-large')
def _getShaded(self,ptopo): maxvalue = self.contour_colormap.vmax ls1 = LightSource(azdeg = 120, altdeg = 45) ls2 = LightSource(azdeg = 225, altdeg = 45) intensity1 = ls1.hillshade(ptopo, fraction = 0.25, vert_exag = VERT_EXAG) intensity2 = ls2.hillshade(ptopo, fraction = 0.25, vert_exag = VERT_EXAG) intensity = intensity1*0.5 + intensity2*0.5 ptoposc = ptopo/maxvalue rgba = self.contour_colormap.cmap(ptoposc) rgb = np.squeeze(rgba) draped_hsv = ls1.blend_hsv(rgb,np.expand_dims(intensity,2)) return draped_hsv
class LightFilter(BaseFilter): "simple gauss filter" def __init__(self, sigma, fraction=0.5): self.gauss_filter = GaussianFilter(sigma, alpha=1) self.light_source = LightSource() self.fraction = fraction #hsv_min_val=0.5,hsv_max_val=0.9, # hsv_min_sat=0.1,hsv_max_sat=0.1) def get_pad(self, dpi): return self.gauss_filter.get_pad(dpi) def process_image(self, padded_src, dpi): t1 = self.gauss_filter.process_image(padded_src, dpi) elevation = t1[:,:,3] rgb = padded_src[:,:,:3] rgb2 = self.light_source.shade_rgb(rgb, elevation, fraction=self.fraction) tgt = np.empty_like(padded_src) tgt[:,:,:3] = rgb2 tgt[:,:,3] = padded_src[:,:,3] return tgt
def display_depth_matplotlib(z): """ Same as above but using matplotlib instead. """ from mpl_toolkits.mplot3d import Axes3D from matplotlib.colors import LightSource m, n = z.shape x, y = np.mgrid[0:m, 0:n] fig = plt.figure() ax = fig.gca(projection='3d') ls = LightSource(azdeg=0, altdeg=65) greyvals = ls.shade(z, plt.cm.Greys) ax.plot_surface(x, y, z, rstride=1, cstride=1, linewidth=0, antialiased=False, facecolors=greyvals) plt.axis('off') plt.axis('equal') plt.show()
def display_colorbar(): """Display a correct numeric colorbar for a shaded plot.""" y, x = np.mgrid[-4:2:200j, -4:2:200j] z = 10 * np.cos(x**2 + y**2) cmap = plt.cm.copper ls = LightSource(315, 45) rgb = ls.shade(z, cmap) fig, ax = plt.subplots() ax.imshow(rgb) # Use a proxy artist for the colorbar... im = ax.imshow(z, cmap=cmap) im.remove() fig.colorbar(im) ax.set_title('Using a colorbar with a shaded plot', size='x-large')
def main3(): ax = plt.axes(projection=ccrs.PlateCarree()) elev, crs, extent = io_srtm.srtm_composite(-5, 52, 2, 2) elev = np.ma.masked_less_equal(elev, 0, copy=False) use_mpl_light_source = False if use_mpl_light_source: from matplotlib.colors import LightSource ls = LightSource(azdeg=90, altdeg=80, hsv_min_val=0.6, hsv_min_sat=0.9, hsv_max_val=0.8, hsv_max_sat=1, ) rgb = ls.shade(elev, plt.get_cmap('Greens', 3)) else: import matplotlib.colors as mcolors rgb = set_shade(elev, cmap=mcolors.ListedColormap([plt.get_cmap('Greens', 3)(0.5)]) ) ax.imshow(rgb, extent=extent, transform=crs ) x = np.linspace(extent[0], extent[1], elev.shape[0]) y = np.linspace(extent[2], extent[3], elev.shape[1]) # # ax.contour(x, y, elev, 100, # linestyles='-', # colors='blue', # linewidths=0.3, # alpha=0.4, # transform=crs, # ) plt.show()
def plot_dem(self,dem_file,region='all',azdeg=100,altdeg=65): """ Plot a DEM using light-shading on the Basemap. Inputs: dem_file : path and filename of GeoTIFF DEM. region : 'all' or latlon tuple (lonll,lonur,latll,latur) azdeg/altdeg : azimuth (measured clockwise from south) and altitude (measured up from the plane of the surface) of the light source in degrees. """ if region == 'all': dem = georaster.SingleBandRaster(dem_file) else: dem = georaster.SingleBandRaster(dem_file,load_data=region, latlon=True) ls = LightSource(azdeg=azdeg,altdeg=altdeg) rgb = ls.shade(dem.r,cmap=cm.Greys_r) plt.imshow(rgb,extent=dem.get_extent_projected(self.map), interpolation='nearest')
def avoid_outliers(): """Use a custom norm to control the displayed z-range of a shaded plot.""" y, x = np.mgrid[-4:2:200j, -4:2:200j] z = 10 * np.cos(x**2 + y**2) # Add some outliers... z[100, 105] = 2000 z[120, 110] = -9000 ls = LightSource(315, 45) fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(8, 4.5)) rgb = ls.shade(z, plt.cm.copper) ax1.imshow(rgb) ax1.set_title('Full range of data') rgb = ls.shade(z, plt.cm.copper, vmin=-10, vmax=10) ax2.imshow(rgb) ax2.set_title('Manually set range') fig.suptitle('Avoiding Outliers in Shaded Plots', size='x-large')
def mapwithtopo(p,ax=[],cutdepth=[],aspect=2.5,cmap=[],dlon=30,dlat=10,smooth=False): import popy,os from netCDF4 import Dataset from mpl_toolkits.basemap import shiftgrid from matplotlib.colors import LightSource import pylab as plt import numpy as np etopofn='/net/mazdata2/jinbo/mdata5-jinbo/obs/ETOPO/ETOPO1_Bed_g_gmt4.grd' etopo = Dataset(etopofn,'r').variables x,y,z=etopo['x'][1:],etopo['y'][1:],etopo['z'][1:,1:] dx,dy=5,5 x=x.reshape(-1,dx).mean(axis=-1) y=y.reshape(-1,dx).mean(axis=-1) z=z.reshape(y.size,dx,x.size,dx).mean(axis=-1).mean(axis=1) if smooth: z=popy.utils.smooth2d(z,window_len=3) if cutdepth!=[]: z[z<cutdepth]=cutdepth if ax==[]: fig=plt.figure() ax=fig.add_subplot() if cmap==[]: cmap=plt.cm.Greys z,x = shiftgrid(p[0],z,x,start=True) lon,lat,z = popy.utils.subtractsubdomain(x,y,p,z) m = setmap(p=p,dlon=dlon,dlat=dlat) x, y = m(*np.meshgrid(lon, lat)) ls = LightSource(azdeg=90, altdeg=45) rgb = ls.shade(z, cmap=cmap) m.imshow(rgb, aspect=aspect) plt.savefig('/tmp/tmp.png') os.popen('eog /tmp/tmp.png') return etopo
def compare(z, cmap, ve=1): # Create subplots and hide ticks fig, axes = plt.subplots(ncols=2, nrows=2) for ax in axes.flat: ax.set(xticks=[], yticks=[]) # Illuminate the scene from the northwest ls = LightSource(azdeg=315, altdeg=45) axes[0, 0].imshow(z, cmap=cmap) axes[0, 0].set(xlabel='Colormapped Data') axes[0, 1].imshow(ls.hillshade(z, vert_exag=ve), cmap='gray') axes[0, 1].set(xlabel='Illumination Intensity') rgb = ls.shade(z, cmap=cmap, vert_exag=ve, blend_mode='hsv') axes[1, 0].imshow(rgb) axes[1, 0].set(xlabel='Blend Mode: "hsv" (default)') rgb = ls.shade(z, cmap=cmap, vert_exag=ve, blend_mode='overlay') axes[1, 1].imshow(rgb) axes[1, 1].set(xlabel='Blend Mode: "overlay"') return fig
def _getDraped(self,data,topodata): maxvalue = self.intensity_colormap.vmax mmisc = data/maxvalue rgba_img = self.intensity_colormap.cmap(mmisc) rgb = np.squeeze(rgba_img[:,:,0:3]) #use lightsource class to make our shaded topography ls = LightSource(azdeg=135,altdeg=45) # intensity = ls.hillshade(ptopo,fraction=0.25,vert_exag=1.0) ls1 = LightSource(azdeg = 120, altdeg = 45) ls2 = LightSource(azdeg = 225, altdeg = 45) intensity1 = ls1.hillshade(topodata, fraction = 0.25, vert_exag = VERT_EXAG) intensity2 = ls2.hillshade(topodata, fraction = 0.25, vert_exag = VERT_EXAG) intensity = intensity1*0.5 + intensity2*0.5 draped_hsv = ls.blend_hsv(rgb,np.expand_dims(intensity,2)) return draped_hsv
def plot_density_sphere(xyz_centers, H, ax=None, method='hist', azimuth=None, elevation=None, backend='visvis', oversample=1, smoothing=None, zoom=1.7, cmap='jet', scaling='log', log_offset=-.1, clim=None, isometric=False, light_ambient=.6, light_specular=.5, avg_direction=None, pitch_label=True, roll_label=True, pitch_arrow=True, roll_arrow=True, arrow_color=(.25, .95, .8), close_figure=False): if azimuth is None: azimuth = DEFAULT_AZIMUTH if elevation is None: elevation = DEFAULT_ELEVATION scaling = scaling.lower() if scaling.startswith('log'): H = H / float(H.sum()) v = H > 0 if scaling == 'log': H[v] = np.log(H[v]) elif scaling == 'log2': H[v] = np.log2(H[v]) H[~v] = H[v].min() + log_offset if smoothing is not None and smoothing > 1: x = np.linspace(-3., 3., smoothing) xx, yy = np.meshgrid(x, x) G = np.exp((-xx**2 - yy**2)) H = signal.convolve2d(H, G / G.sum(), mode='same', boundary='wrap') if backend in ['mpl', 'matplotlib']: if ax is None: fig = plt.figure() ax = fig.add_subplot(111, projection='3d') from matplotlib.colors import LightSource ls = LightSource(azdeg=315, altdeg=45) cm = getattr(plt.cm, cmap) colors = ls.shade(H, cmap=cm, blend_mode='soft', vert_exag=1) ax.plot_surface(xyz_centers[:, 0].reshape(H), xyz_centers[:, 1].reshape(H), xyz_centers[:, 2].reshape(H), cstride=1, rstride=1, facecolors=colors, linewidth=0, antialiased=False, shade=False) # add arrows in front of sphere import mousecam_helpers as helpers arrow_props = dict(arrowstyle='simple', mutation_scale=15, mutation_aspect=None, linewidth=.5, facecolor=3 * [.75], edgecolor=3 * [.1]) length = .6 arr = helpers.Arrow3D((1, 1 + length), (0, 0), (0, 0), **arrow_props) ax.add_artist(arr) arr = helpers.Arrow3D((0, 0), (1, 1 + length), (0, 0), **arrow_props) ax.add_artist(arr) arr = helpers.Arrow3D((0, 0), (0, 0), (1, 1 + length), **arrow_props) ax.add_artist(arr) extents = 3 * [[-.6, .6]] ax.auto_scale_xyz(*extents) ax.set_aspect('equal') ax.axis('off') ax.view_init(elev=elevation, azim=360 - azimuth) elif backend in ['mayavi', 'mlab']: from mayavi import mlab fig = mlab.figure(bgcolor=(1, 1, 1), size=(1000, 1000)) fig.scene.parallel_projection = True mlab.mesh(xyz_centers[:, 0].reshape(H.shape), xyz_centers[:, 1].reshape(H.shape), xyz_centers[:, 2].reshape(H.shape), scalars=H, colormap='jet') from tvtk.tools import visual visual.set_viewer(fig) arrow_kw = dict(color=(.75, .75, .75), length_cone=.1, radius_cone=.05, radius_shaft=.025) Arrow3D(0, 0, 0, 1.4, 0, 0, **arrow_kw) Arrow3D(0, 0, 0, 0, 1.4, 0, **arrow_kw) Arrow3D(0, 0, 0, 0, 0, 1.4, **arrow_kw) if isometric: fig.scene.isometric_view() else: mlab.view(azimuth=-azimuth, elevation=elevation, figure=fig) fig.scene.camera.zoom(zoom) ax = mlab.screenshot(figure=fig, mode='rgb', antialiased=False) elif backend in ['visvis']: import visvis as vv app = vv.use() fig = vv.figure() ax = vv.subplot(111) ax.axis.visible = 0 ax.axis.xLabel = 'x' ax.axis.yLabel = 'y' ax.axis.zLabel = 'z' length = 1.4 for i in range(3): direction = np.zeros((3, )) direction[i] = 1 cyl = vv.solidCylinder(translation=(0, 0, 0), scaling=(.05, .05, length), direction=tuple(direction), axesAdjust=False, axes=ax) cyl.faceColor = (.75, .75, .75) translation = np.zeros((3, )) translation[i] = length cone = vv.solidCone(translation=tuple(translation), scaling=(.1, .1, .2), direction=tuple(direction), axesAdjust=False, axes=ax) cone.faceColor = (.75, .75, .75) surf = vv.surf(xyz_centers[:, 0].reshape(H.shape), xyz_centers[:, 1].reshape(H.shape), xyz_centers[:, 2].reshape(H.shape), H, axes=ax) # set colormap cmap = cmap.lower() if cmap.endswith('_r'): cm = vv.colormaps[cmap[:-2]] cm = cm[::-1] else: cm = vv.colormaps[cmap] surf.colormap = cm if clim is not None: # apply colormap limits surf.clim = clim # ax.Draw() # add labels to indicate pitch and/or roll axes aa = np.deg2rad(np.linspace(45, 315, 100) - 90) r = .25 + .05 d = 1.25 + .25 color = (.25, .25, .25) if pitch_arrow: # pitch rotation (in x/z plane, i.e. around y-axis) xx = r * np.cos(aa) zz = r * np.sin(aa) yy = d * np.ones_like(xx) vv.plot(xx, yy, zz, lw=5, lc=color, ls="-", axesAdjust=False, axes=ax) translation = (xx[0], yy[0], zz[0]) direction = (xx[0] - xx[1], yy[0] - yy[1], zz[0] - zz[1]) cone = vv.solidCone(translation=translation, scaling=(.05, .05, .1), direction=direction, axesAdjust=False, axes=ax) cone.faceColor = color if pitch_label: vv.Text(ax, 'Pitch', x=0, y=.9 * d, z=.5, fontSize=28, color=color) if roll_arrow: # roll rotation (in y/z plane, i.e. around x-axis) yy = r * np.cos(aa[::-1]) zz = r * np.sin(aa[::-1]) xx = d * np.ones_like(xx) vv.plot(xx, yy, zz, lw=5, lc=color, ls="-", axesAdjust=False, axes=ax) translation = (xx[0], yy[0], zz[0]) direction = (xx[0] - xx[1], yy[0] - yy[1], zz[0] - zz[1]) cone = vv.solidCone(translation=translation, scaling=(.05, .05, .1), direction=direction, axesAdjust=False, axes=ax) cone.faceColor = color if roll_label: vv.Text(ax, 'Roll', x=1.25 * d, y=-.8, z=0, fontSize=28, color=color) if avg_direction is not None: # indicate direction of avg head orientation avg_direction = avg_direction / np.sqrt(np.sum(avg_direction**2)) avg_direction *= length cyl = vv.solidCylinder(translation=(0, 0, 0), scaling=(.05, .05, length), direction=tuple(avg_direction), axesAdjust=False, axes=ax) cyl.faceColor = arrow_color cone = vv.solidCone(translation=tuple(avg_direction), scaling=(.1, .1, .2), direction=tuple(avg_direction), axesAdjust=False, axes=ax) cone.faceColor = arrow_color zoom_ = vv.view()['zoom'] if isometric: vv.view(dict(azimuth=90 + ISO_AZIMUTH, elevation=ISO_ELEVATION), zoom=zoom_ * zoom, axes=ax) else: vv.view(dict(azimuth=90 + azimuth, elevation=elevation), zoom=zoom * zoom_, axes=ax) ax.light0.ambient = light_ambient ax.light0.specular = light_specular fig.DrawNow() app.ProcessEvents() img = vv.screenshot(None, ob=ax, sf=2, bg=None, format=None) ax = img if close_figure: vv.close(fig) fig = None return fig, ax
#-- Optional dx and dy for accurate vertical exaggeration -------------------- # If you need topographically accurate vertical exaggeration, or you don't want # to guess at what *vert_exag* should be, you'll need to specify the cellsize # of the grid (i.e. the *dx* and *dy* parameters). Otherwise, any *vert_exag* # value you specify will be realitive to the grid spacing of your input data # (in other words, *dx* and *dy* default to 1.0, and *vert_exag* is calculated # relative to those parameters). Similarly, *dx* and *dy* are assumed to be in # the same units as your input z-values. Therefore, we'll need to convert the # given dx and dy from decimal degrees to meters. dx, dy = dem['dx'], dem['dy'] dy = 111200 * dy dx = 111200 * dx * np.cos(np.radians(dem['ymin'])) #----------------------------------------------------------------------------- # Shade from the northwest, with the sun 45 degrees from horizontal ls = LightSource(azdeg=315, altdeg=45) cmap = plt.cm.gist_earth fig, axes = plt.subplots(nrows=4, ncols=3, figsize=(8, 9)) plt.setp(axes.flat, xticks=[], yticks=[]) # Vary vertical exaggeration and blend mode and plot all combinations for col, ve in zip(axes.T, [0.1, 1, 10]): # Show the hillshade intensity image in the first row col[0].imshow(ls.hillshade(z, vert_exag=ve, dx=dx, dy=dy), cmap='gray') # Place hillshaded plots with different blend modes in the rest of the rows for ax, mode in zip(col[1:], ['hsv', 'overlay', 'soft']): rgb = ls.shade(z, cmap=cmap, blend_mode=mode,
from mpl_toolkits.mplot3d import Axes3D from matplotlib import cbook from matplotlib import cm from matplotlib.colors import LightSource import matplotlib.pyplot as plt import numpy as np filename = cbook.get_sample_data('jacksboro_fault_dem.npz', asfileobj=False) with np.load(filename) as dem: z = dem['elevation'] nrows, ncols = z.shape x = np.linspace(dem['xmin'], dem['xmax'], ncols) y = np.linspace(dem['ymin'], dem['ymax'], nrows) x, y = np.meshgrid(x, y) region = np.s_[5:50, 5:50] x, y, z = x[region], y[region], z[region] fig, ax = plt.subplots(subplot_kw=dict(projection='3d'), figsize=(1.62, 1.38)) ls = LightSource(270, 45) # To use a custom hillshading mode, override the built-in shading and pass # in the rgb colors of the shaded surface calculated from "shade". rgb = ls.shade(z, cmap=cm.gist_earth, vert_exag=0.1, blend_mode='soft') surf = ax.plot_surface(x, y, z, rstride=1, cstride=1, facecolors=rgb, linewidth=0, antialiased=False, shade=False) ax.set_xticks([]) ax.set_yticks([]) ax.set_zticks([]) fig.savefig("surface3d_frontpage.png")
lons = np.loadtxt('etopo20lons.gz') lats = np.loadtxt('etopo20lats.gz') # shift data so lons go from -180 to 180 instead of 20 to 380. topoin,lons = shiftgrid(180.,topoin,lons,start=False) # setup of basemap ('lcc' = lambert conformal conic). # use major and minor sphere radii from WGS84 ellipsoid. m = Basemap(llcrnrlon=-145.5,llcrnrlat=1.,urcrnrlon=-2.566,urcrnrlat=46.352,\ rsphere=(6378137.00,6356752.3142),\ resolution='l',area_thresh=1000.,projection='lcc',\ lat_1=50.,lon_0=-107.) # transform to nx x ny regularly spaced native projection grid nx = int((m.xmax-m.xmin)/40000.)+1; ny = int((m.ymax-m.ymin)/40000.)+1 topodat,x,y = m.transform_scalar(topoin,lons,lats,nx,ny,returnxy=True) # create light source object. ls = LightSource(azdeg = 90, altdeg = 20) # convert data to rgb array including shading from light source. # (must specify color map) rgb = ls.shade(topodat, plt.cm.jet) # create the figure. fig=plt.figure(figsize=(8,8)) # plot image over map with imshow (pass rgb values # that include light shading). im = m.imshow(rgb) # draw coastlines and political boundaries. m.drawcoastlines() m.drawcountries() # draw parallels and meridians. # label on left, right and bottom of map. parallels = np.arange(0.,80,20.) m.drawparallels(parallels,labels=[1,1,0,1])
def plot_perturb_plt(rx, ry, loss, predict, z_by_loss=True, color_by_loss=False, color='viridis', min_value=None, max_value=None, title=None, width=8, height=7, linewidth=0.1, x_ratio=1, y_ratio=1, z_ratio=1, edge_color='#f2fafb', colorbar_yticklabels=None, pane_color=(1.0, 1.0, 1.0, 0.0), tick_pad_x=0, tick_pad_y=0, tick_pad_z=1.5, xticks=None, yticks=None, zticks=None, xlabel=None, ylabel=None, zlabel=None, xlabel_rotation=0, ylabel_rotation=0, zlabel_rotation=0, view_azimuth=230, view_altitude=30, light_azimuth=315, light_altitude=45, light_exag=0): if z_by_loss: zs = loss else: zs = predict if color_by_loss: colors = loss else: colors = predict xs, ys = np.meshgrid(rx, ry) fig = plt.figure(figsize=(width, height)) ax = plt.axes(projection='3d') if title is not None: ax.set_title(title) if min_value is None: min_value = int(colors.min()) if max_value is None: max_value = int(colors.max()) if 'float' in str(colors.dtype): scamap = cm.ScalarMappable(cmap=get_cmap(color)) else: scamap = cm.ScalarMappable(cmap=get_cmap(color, max_value - min_value + 1)) scamap.set_array(colors) scamap.set_clim(vmax=max_value + .5, vmin=min_value - .5) # The azimuth (0-360, degrees clockwise from North) of the light source. Defaults to 315 degrees (from the northwest). # The altitude (0-90, degrees up from horizontal) of the light source. Defaults to 45 degrees from horizontal. ls = LightSource(azdeg=light_azimuth, altdeg=light_altitude) fcolors = ls.shade(colors, cmap=scamap.cmap, vert_exag=light_exag, blend_mode='soft') surf = ax.plot_surface(xs, ys, zs, rstride=1, cstride=1, facecolors=fcolors, linewidth=linewidth, antialiased=True, shade=False) surf.set_edgecolor(edge_color) ax.view_init(azim=view_azimuth, elev=view_altitude) # You can change 0.01 to adjust the distance between the main image and the colorbar. # You can change 0.02 to adjust the width of the colorbar. cax = fig.add_axes([ ax.get_position().x1 + 0.01, ax.get_position().y0 + ax.get_position().height / 8, 0.02, ax.get_position().height / 4 * 3 ]) cbar = plt.colorbar(scamap, ticks=np.linspace(min_value, max_value, max_value - min_value + 1), cax=cax) if colorbar_yticklabels is not None: cbar.ax.set_yticklabels(colorbar_yticklabels) ax.xaxis.set_rotate_label(False) ax.yaxis.set_rotate_label(False) ax.zaxis.set_rotate_label(False) if xlabel is not None: ax.set_xlabel(xlabel, rotation=xlabel_rotation) if ylabel is not None: ax.set_ylabel(ylabel, rotation=ylabel_rotation) if zlabel is not None: ax.set_zlabel(zlabel, rotation=zlabel_rotation) if xticks is not None: ax.set_xticks(xticks) if yticks is not None: ax.set_yticks(yticks) if zticks is not None: ax.set_zticks(zticks) ax.xaxis.set_pane_color(pane_color) ax.yaxis.set_pane_color(pane_color) ax.zaxis.set_pane_color(pane_color) ax.tick_params(axis='x', pad=tick_pad_x) ax.tick_params(axis='y', pad=tick_pad_y) ax.tick_params(axis='z', pad=tick_pad_z)
# Calcul à part pour la section de coupe. x_trou = np.arange(-trou / 2, trou / 2, dx) Zcut = (sum([point_source(x, ycut, t, xt, 0, theta) for xt in x_trou]) / len(x_trou))**2 # Ouverture de la figure et définition des sous-figures plt.figure(figsize=(8, 6.9)) ax1 = plt.subplot2grid((3, 2), (0, 0), colspan=2, rowspan=2) plt.title('Diffraction par une ouverture plane, $t={}$'.format(round(t, 1))) plt.ylabel('$y$') plt.xlim((xmin, xmax)) plt.ylim((ymin, ymax)) if shading: ls = LightSource(azdeg=20, altdeg=65) # create light source object. # shade data, creating an rgb array. rgb = ls.shade(Z, plt.cm.copper) plt.imshow(rgb, extent=extent) else: plt.imshow(Z, interpolation='bilinear', extent=extent, cmap='jet', vmin=vmin, vmax=vmax) # On rajoute deux barres pour les murs plt.annotate('', xytext=(-ext, 0), xy=(-trou / 2, 0),
def animate_interactive(data, t = [], dimOrder = (0,1,2), fps = 10.0, title = '', xlabel = 'x', ylabel = 'y', fontsize = 24, cBar = 0, sloppy = True, rangeMin = [], rangeMax = [], extent = [-1,1,-1,1], shade = False, azdeg = 0, altdeg = 65, arrowsX = np.array(0), arrowsY = np.array(0), arrowsRes = 10, arrowsPivot = 'mid', arrowsWidth = 0.002, arrowsScale = 5, arrowsColor = 'black', plotArrowsGrid = False, movieFile = '', bitrate = 1800, keepImages = False, figsize = (8, 7), dpi = None, **kwimshow): """ Assemble a 2D animation from a 3D array. call signature:: animate_interactive(data, t = [], dimOrder = (0,1,2), fps = 10.0, title = '', xlabel = 'x', ylabel = 'y', fontsize = 24, cBar = 0, sloppy = True, rangeMin = [], rangeMax = [], extent = [-1,1,-1,1], shade = False, azdeg = 0, altdeg = 65, arrowsX = np.array(0), arrowsY = np.array(0), arrowsRes = 10, arrowsPivot = 'mid', arrowsWidth = 0.002, arrowsScale = 5, arrowsColor = 'black', plotArrowsGrid = False, movieFile = '', bitrate = 1800, keepImages = False, figsize = (8, 7), dpi = None, **kwimshow) Assemble a 2D animation from a 3D array. *data* has to be a 3D array who's time index has the same dimension as *t*. The time index of *data* as well as its x and y indices can be changed via *dimOrder*. Keyword arguments: *dimOrder*: [ (i,j,k) ] Ordering of the dimensions in the data array (t,x,y). *fps*: Frames per second of the animation. *title*: Title of the plot. *xlabel*: Label of the x-axis. *ylabel*: Label of the y-axis. *fontsize*: Font size of the title, x and y label. The size of the x- and y-ticks is 0.7*fontsize and the colorbar ticks's font size is 0.5*fontsize. *cBar*: [ 0 | 1 | 2 ] Determines how the colorbar changes: (0 - no cahnge; 1 - keep extreme values constant; 2 - change extreme values). *sloppy*: [ True | False ] If True the update of the plot lags one frame behind. This speeds up the plotting. *rangeMin*, *rangeMax*: Range of the colortable. *extent*: [ None | scalars (left, right, bottom, top) ] Data limits for the axes. The default assigns zero-based row, column indices to the *x*, *y* centers of the pixels. *shade*: [ False | True ] If True plot a shaded relief plot instead of the usual colormap. Note that with this option cmap has to be specified like cmap = plt.cm.hot instead of cmap = 'hot'. Shading cannot be used with the cBar = 0 option. *azdeg*, *altdeg*: Azimuth and altitude of the light source for the shading. *arrowsX*: Data containing the x-component of the arrows. *arrowsy*: Data containing the y-component of the arrows. *arrowsRes*: Plot every arrowRes arrow. *arrowsPivot*: [ 'tail' | 'middle' | 'tip' ] The part of the arrow that is at the grid point; the arrow rotates about this point. *arrowsWidth*: Width of the arrows. *arrowsScale*: Scaling of the arrows. *arrowsColor*: Color of the arrows. *plotArrowsGrid*: [ False | True ] If 'True' the grid where the arrows are aligned to is shown. *movieFile*: [ None | string ] The movie file where the animation should be saved to. If 'None' no movie file is written. Requires 'mencoder' to be installed. *bitrate*: Bitrate of the movie file. Set to higher value for higher quality. *keepImages*: [ False | True ] If 'True' the images for the movie creation are not deleted. *figsize*: Size of the figure in inches. *dpi*: Dots per inch of the frame. **kwimshow: Remaining arguments are identical to those of pylab.imshow. Refer to that help. """ import pylab as plt import time import os # for making the movie try: import thread # for GUI except: import _thread as thread from matplotlib.colors import LightSource global tStep, sliderTime, pause # plot the current frame def plotFrame(): global tStep, sliderTime if movieFile: ax.set_title(title+r'$\quad$'+r'$t={0}$'.format(t[tStep]), fontsize = fontsize) if shade == False: image.set_data(data[tStep,:,:]) else: image.set_data(rgb[tStep,:,:,:]) if (cBar == 0): pass if (cBar == 1): colorbar.set_clim(vmin=data[tStep,:,:].min(), vmax=data[tStep,:,:].max()) if (cBar == 2): colorbar.set_clim(vmin=data[tStep,:,:].min(), vmax=data[tStep,:,:].max()) colorbar.update_bruteforce(data[tStep,:,:]) if plotArrows: arrows.set_UVC(U = arrowsX[tStep,::arrowsRes,::arrowsRes], V = arrowsY[tStep,::arrowsRes,::arrowsRes]) if (sloppy == False) or (movieFile): manager.canvas.draw() # play the movie def play(threadName): global tStep, sliderTime, pause pause = False while (tStep < nT) & (pause == False): # write the image files for the movie if movieFile: plotFrame() frameName = movieFile + '%06d.png'%tStep fig.savefig(frameName, dpi = dpi) movieFiles.append(frameName) else: start = time.clock() # time slider sliderTime.set_val(t[tStep]) # wait for the next frame (fps) while (time.clock() - start < 1.0/fps): pass # do nothing tStep += 1 tStep -= 1 # call the play function as a separate thread (for GUI) def play_thread(event): global pause if pause == True: try: thread.start_new_thread(play, ("playThread", )) except: print("Error: unable to start play thread") def pausing(event): global pause pause = True def reverse(event): global tStep, sliderTime tStep -= 1 if tStep < 0: tStep = 0 # plot the frame and update the time slider sliderTime.set_val(t[tStep]) def forward(event): global tStep, sliderTime tStep += 1 if tStep > len(t)-1: tStep = len(t)-1 # plot the frame and update the time slider sliderTime.set_val(t[tStep]) pause = True plotArrows = False # check if the data has the right dimensions if (len(data.shape) != 3 and len(data.shape) != 4): print("error: data dimensions are invalid: {0} instead of 3".format(len(data.shape))) return -1 # transpose the data according to dimOrder unOrdered = data data = np.transpose(unOrdered, dimOrder) unOrdered = [] # check if arrows should be plotted if len(arrowsX.shape) == 3: # transpose the data according to dimOrder unOrdered = arrowsX arrowsX = np.transpose(unOrdered, dimOrder) unOrdered = [] if len(arrowsY.shape) == 3: # transpose the data according to dimOrder unOrdered = arrowsY arrowsY = np.transpose(unOrdered, dimOrder) unOrdered = [] # check if the dimensions of the arrow arrays match each other if ((len(arrowsX[:,0,0]) != len(arrowsY[:,0,0])) or (len(arrowsX[0,:,0]) != len(arrowsY[0,:,0])) or (len(arrowsX[0,0,:]) != len(arrowsY[0,0,:]))): print("error: dimensions of arrowX do not match with dimensions of arrowY") return -1 else: plotArrows = True # check if time array has the right length nT = len(t) if (nT != len(data[:,0,0])): print("error: length of time array doesn\'t match length of data array") return -1 if plotArrows: if (nT != len(arrowsX[:,0,0]) or nT != len(arrowsX[:,0,0])): print("error: length of time array doesn\'t match length of arrows array") return -1 # check if fps is positive if (fps < 0.0): print("error: fps is not positive, fps = {0}".format(fps)) return -1 # determine the size of the array nX = len(data[0,:,0]) nY = len(data[0,0,:]) # determine the minimum and maximum values of the data set if not(rangeMin): rangeMin = np.min(data) if not(rangeMax): rangeMax = np.max(data) # setup the plot if movieFile: plt.rc("figure.subplot", bottom=0.15) plt.rc("figure.subplot", top=0.95) plt.rc("figure.subplot", right=0.95) plt.rc("figure.subplot", left=0.15) fig = plt.figure(figsize = figsize) ax = plt.axes([0.1, 0.1, .90, .85]) else: plt.rc("figure.subplot", bottom=0.05) plt.rc("figure.subplot", top=0.95) plt.rc("figure.subplot", right=0.95) plt.rc("figure.subplot", left=0.15) fig = plt.figure(figsize = figsize) ax = plt.axes([0.1, 0.25, .85, .70]) ax.set_title(title, fontsize = fontsize) ax.set_xlabel(xlabel, fontsize = fontsize) ax.set_ylabel(ylabel, fontsize = fontsize) plt.xticks(fontsize = 0.7*fontsize) plt.yticks(fontsize = 0.7*fontsize) if shade: plane = np.zeros((nX,nY,3)) else: plane = np.zeros((nX,nY)) # apply shading if True if shade: ls = LightSource(azdeg = azdeg, altdeg = altdeg) rgb = [] # shading can be only used with cBar = 1 or cBar = 2 at the moment if cBar == 0: cBar = 1 # check if colormap is set, if not set it to 'copper' if not 'cmap' in kwimshow.keys(): kwimshow['cmap'] = plt.cm.copper for i in range(len(data[:,0,0])): tmp = ls.shade(data[i,:,:], kwimshow['cmap']) rgb.append(tmp.tolist()) rgb = np.array(rgb) tmp = [] # calibrate the displayed colors for the data range image = ax.imshow(plane, vmin=rangeMin, vmax=rangeMax, origin='lower', extent = extent, **kwimshow) colorbar = fig.colorbar(image) # change the font size of the colorbar's ytickslabels cbytick_obj = plt.getp(colorbar.ax.axes, 'yticklabels') plt.setp(cbytick_obj, fontsize = 0.5*fontsize) # plot the arrows # TODO: add some more options if plotArrows: # prepare the mash grid where the arrows will be drawn arrowGridX, arrowGridY = np.meshgrid(np.arange(extent[0], extent[1], float(extent[1]-extent[0])*arrowsRes/len(data[0,:,0])), np.arange(extent[2], extent[3], float(extent[3]-extent[2])*arrowsRes/len(data[0,0,:]))) arrows = ax.quiver(arrowGridX, arrowGridY, arrowsX[0,::arrowsRes,::arrowsRes], arrowsY[0,::arrowsRes,::arrowsRes], units = 'width', pivot = arrowsPivot, width = arrowsWidth, scale = arrowsScale, color = arrowsColor) # plot the grid for the arrows if plotArrowsGrid == True: ax.plot(arrowGridX, arrowGridY, 'k.') # for real-time image display if (sloppy == False) or (movieFile): manager = plt.get_current_fig_manager() manager.show() tStep = 0 if movieFile: movieFiles = [] # start the animation play('noThread') # write the movie file mencodeCommand = "mencoder 'mf://"+movieFile+"*.png' -mf type=png:fps="+np.str(fps)+" -ovc lavc -lavcopts vcodec=mpeg4:vhq:vbitrate="+np.str(bitrate)+" -ffourcc MP4S -oac copy -o "+movieFile+".mpg" os.system(mencodeCommand) # clean up the image files if (keepImages == False): print("cleaning up files") for fname in movieFiles: os.remove(fname) else: # set up the gui plt.ion() axPlay = plt.axes([0.1, 0.05, 0.15, 0.05], axisbg='lightgoldenrodyellow') buttonPlay = plt.Button(axPlay, 'play', color='lightgoldenrodyellow', hovercolor='0.975') buttonPlay.on_clicked(play_thread) axPause = plt.axes([0.3, 0.05, 0.15, 0.05], axisbg='lightgoldenrodyellow') buttonPause = plt.Button(axPause, 'pause', color='lightgoldenrodyellow', hovercolor='0.975') buttonPause.on_clicked(pausing) axReverse = plt.axes([0.5, 0.05, 0.15, 0.05], axisbg='lightgoldenrodyellow') buttonReverse = plt.Button(axReverse, 'reverse', color='lightgoldenrodyellow', hovercolor='0.975') buttonReverse.on_clicked(reverse) axForward = plt.axes([0.7, 0.05, 0.15, 0.05], axisbg='lightgoldenrodyellow') buttonForward = plt.Button(axForward, 'forward', color='lightgoldenrodyellow', hovercolor='0.975') buttonForward.on_clicked(forward) # create the time slider fig.subplots_adjust(bottom=0.2) sliderTimeAxes = plt.axes([0.2, 0.12, 0.6, 0.03], axisbg='lightgoldenrodyellow') sliderTime = plt.Slider(sliderTimeAxes, 'time', t[0], t[-1], valinit = 0.0) def update(val): global tStep # find the closest time step to the slider time value for i in range(len(t)): if t[i] < sliderTime.val: tStep = i if (tStep != len(t)-1): if (t[tStep+1] - sliderTime.val) < (sliderTime.val - t[tStep]): tStep += 1 plotFrame() sliderTime.on_changed(update) plt.show() print("done")
def draw_3d(self): """ Draw various 3D plots """ self.init_axes() bb = fb.fil[0]['ba'][0] aa = fb.fil[0]['ba'][1] zz = np.array(fb.fil[0]['zpk'][0]) pp = np.array(fb.fil[0]['zpk'][1]) wholeF = fb.fil[0]['freqSpecsRangeType'] != 'half' # not used f_S = fb.fil[0]['f_S'] N_FFT = params['N_FFT'] alpha = self.diaAlpha.value() / 10. cmap = cm.get_cmap(str(self.cmbColormap.currentText())) if self.chkColormap_r.isChecked(): cmap = cmap.reversed() # use reversed colormap # Number of Lines /step size for H(f) stride, mesh, contour3d: stride = 10 - self.diaHatch.value() NL = 3 * self.diaHatch.value() + 5 surf_enabled = qget_cmb_box(self.cmbMode3D, data=False) in {'Surf', 'Contour'} self.cmbColormap.setEnabled(surf_enabled) self.chkColormap_r.setEnabled(surf_enabled) self.chkLighting.setEnabled(surf_enabled) self.chkColBar.setEnabled(surf_enabled) self.diaAlpha.setEnabled(surf_enabled or self.chkContour2D.isChecked()) #cNorm = colors.Normalize(vmin=0, vmax=values[-1]) #scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet) #----------------------------------------------------------------------------- # Calculate H(w) along the upper half of unity circle #----------------------------------------------------------------------------- [w, H] = sig.freqz(bb, aa, worN=N_FFT, whole=True) H = np.nan_to_num(H) # replace nans and inf by finite numbers H_abs = abs(H) H_max = max(H_abs) H_min = min(H_abs) #f = w / (2 * pi) * f_S # translate w to absolute frequencies #F_min = f[np.argmin(H_abs)] plevel_rel = 1.05 # height of plotted pole position relative to zmax zlevel_rel = 0.1 # height of plotted zero position relative to zmax if self.chkLog.isChecked(): # logarithmic scale # suppress "divide by zero in log10" warnings old_settings_seterr = np.seterr() np.seterr(divide='ignore') bottom = np.floor(max(self.zmin_dB, 20 * log10(H_min)) / 10) * 10 top = self.zmax_dB top_bottom = top - bottom zlevel = bottom - top_bottom * zlevel_rel if self.cmbMode3D.currentText( ) == 'None': # "Poleposition" for H(f) plot only plevel_top = 2 * bottom - zlevel # height of displayed pole position plevel_btm = bottom else: plevel_top = top + top_bottom * (plevel_rel - 1) plevel_btm = top np.seterr(**old_settings_seterr) else: # linear scale bottom = max(self.zmin, H_min) # min. display value top = self.zmax # max. display value top_bottom = top - bottom # top = zmax_rel * H_max # calculate display top from max. of H(f) zlevel = bottom + top_bottom * zlevel_rel # height of displayed zero position if self.cmbMode3D.currentText( ) == 'None': # "Poleposition" for H(f) plot only #H_max = np.clip(max(H_abs), 0, self.zmax) # make height of displayed poles same to zeros plevel_top = bottom + top_bottom * zlevel_rel plevel_btm = bottom else: plevel_top = plevel_rel * top plevel_btm = top # calculate H(jw)| along the unity circle and |H(z)|, each clipped # between bottom and top H_UC = H_mag(bb, aa, self.xy_UC, top, H_min=bottom, log=self.chkLog.isChecked()) Hmag = H_mag(bb, aa, self.z, top, H_min=bottom, log=self.chkLog.isChecked()) #=============================================================== ## plot Unit Circle (UC) #=============================================================== if self.chkUC.isChecked(): # Plot unit circle and marker at (1,0): self.ax3d.plot(self.xy_UC.real, self.xy_UC.imag, ones(len(self.xy_UC)) * bottom, lw=2, color='k') self.ax3d.plot([0.97, 1.03], [0, 0], [bottom, bottom], lw=2, color='k') #=============================================================== ## plot ||H(f)| along unit circle as 3D-lineplot #=============================================================== if self.chkHf.isChecked(): self.ax3d.plot(self.xy_UC.real, self.xy_UC.imag, H_UC, alpha=0.8, lw=4) # draw once more as dashed white line to improve visibility self.ax3d.plot(self.xy_UC.real, self.xy_UC.imag, H_UC, 'w--', lw=4) if stride < 10: # plot thin vertical line every stride points on the UC for k in range(len(self.xy_UC[::stride])): self.ax3d.plot([ self.xy_UC.real[::stride][k], self.xy_UC.real[::stride][k] ], [ self.xy_UC.imag[::stride][k], self.xy_UC.imag[::stride][k] ], [ np.ones(len(self.xy_UC[::stride]))[k] * bottom, H_UC[::stride][k] ], linewidth=1, color=(0.5, 0.5, 0.5)) #=============================================================== ## plot Poles and Zeros #=============================================================== if self.chkPZ.isChecked(): PN_SIZE = 8 # size of P/N symbols # Plot zero markers at |H(z_i)| = zlevel with "stems": self.ax3d.plot(zz.real, zz.imag, ones(len(zz)) * zlevel, 'o', markersize=PN_SIZE, markeredgecolor='blue', markeredgewidth=2.0, markerfacecolor='none') for k in range(len(zz)): # plot zero "stems" self.ax3d.plot([zz[k].real, zz[k].real], [zz[k].imag, zz[k].imag], [bottom, zlevel], linewidth=1, color='b') # Plot the poles at |H(z_p)| = plevel with "stems": self.ax3d.plot(np.real(pp), np.imag(pp), plevel_top, 'x', markersize=PN_SIZE, markeredgewidth=2.0, markeredgecolor='red') for k in range(len(pp)): # plot pole "stems" self.ax3d.plot([pp[k].real, pp[k].real], [pp[k].imag, pp[k].imag], [plevel_btm, plevel_top], linewidth=1, color='r') #=============================================================== ## 3D-Plots of |H(z)| clipped between |H(z)| = top #=============================================================== m_cb = cm.ScalarMappable( cmap=cmap) # normalized proxy object that is mappable m_cb.set_array(Hmag) # for colorbar #--------------------------------------------------------------- ## 3D-mesh plot #--------------------------------------------------------------- if self.cmbMode3D.currentText() == 'Mesh': # fig_mlab = mlab.figure(fgcolor=(0., 0., 0.), bgcolor=(1, 1, 1)) # self.ax3d.set_zlim(0,2) self.ax3d.plot_wireframe(self.x, self.y, Hmag, rstride=5, cstride=stride, linewidth=1, color='gray') #--------------------------------------------------------------- ## 3D-surface plot #--------------------------------------------------------------- # http://stackoverflow.com/questions/28232879/phong-shading-for-shiny-python-3d-surface-plots elif self.cmbMode3D.currentText() == 'Surf': if MLAB: ## Mayavi surf = mlab.surf(self.x, self.y, H_mag, colormap='RdYlBu', warp_scale='auto') # Change the visualization parameters. surf.actor.property.interpolation = 'phong' surf.actor.property.specular = 0.1 surf.actor.property.specular_power = 5 # s = mlab.contour_surf(self.x, self.y, Hmag, contour_z=0) mlab.show() else: if self.chkLighting.isChecked(): ls = LightSource(azdeg=0, altdeg=65) # Create light source object rgb = ls.shade( Hmag, cmap=cmap) # Shade data, creating an rgb array cmap_surf = None else: rgb = None cmap_surf = cmap # s = self.ax3d.plot_surface(self.x, self.y, Hmag, # alpha=OPT_3D_ALPHA, rstride=1, cstride=1, cmap=cmap, # linewidth=0, antialiased=False, shade=True, facecolors = rgb) # s.set_edgecolor('gray') s = self.ax3d.plot_surface(self.x, self.y, Hmag, alpha=alpha, rstride=1, cstride=1, linewidth=0, antialiased=False, facecolors=rgb, cmap=cmap_surf, shade=True) s.set_edgecolor(None) #--------------------------------------------------------------- ## 3D-Contour plot #--------------------------------------------------------------- elif self.cmbMode3D.currentText() == 'Contour': s = self.ax3d.contourf3D(self.x, self.y, Hmag, NL, alpha=alpha, cmap=cmap) #--------------------------------------------------------------- ## 2D-Contour plot # TODO: 2D contour plots do not plot correctly together with 3D plots in # current matplotlib 1.4.3 -> disable them for now # TODO: zdir = x / y delivers unexpected results -> rather plot max(H) # along the other axis? # TODO: colormap is created depending on the zdir = 'z' contour plot # -> set limits of (all) other plots manually? if self.chkContour2D.isChecked(): # self.ax3d.contourf(x, y, Hmag, 20, zdir='x', offset=xmin, # cmap=cmap, alpha = alpha)#, vmin = bottom)#, vmax = top, vmin = bottom) # self.ax3d.contourf(x, y, Hmag, 20, zdir='y', offset=ymax, # cmap=cmap, alpha = alpha)#, vmin = bottom)#, vmax = top, vmin = bottom) s = self.ax3d.contourf(self.x, self.y, Hmag, NL, zdir='z', offset=bottom - (top - bottom) * 0.05, cmap=cmap, alpha=alpha) # plot colorbar for suitable plot modes if self.chkColBar.isChecked() and (self.chkContour2D.isChecked() or str(self.cmbMode3D.currentText()) in {'Contour', 'Surf'}): self.colb = self.mplwidget.fig.colorbar(m_cb, ax=self.ax3d, shrink=0.8, aspect=20, pad=0.02, fraction=0.08) #---------------------------------------------------------------------- ## Set view limits and labels #---------------------------------------------------------------------- if not self.mplwidget.mplToolbar.a_lk.isChecked(): self.ax3d.set_xlim3d(self.xmin, self.xmax) self.ax3d.set_ylim3d(self.ymin, self.ymax) self.ax3d.set_zlim3d(bottom, top) else: self._restore_axes() self.ax3d.set_xlabel('Re') #(fb.fil[0]['plt_fLabel']) self.ax3d.set_ylabel( 'Im' ) #(r'$ \tau_g(\mathrm{e}^{\mathrm{j} \Omega}) / T_S \; \rightarrow $') # self.ax3d.set_zlabel(r'$|H(z)|\; \rightarrow $') self.ax3d.set_title( r'3D-Plot of $|H(\mathrm{e}^{\mathrm{j} \Omega})|$ and $|H(z)|$') self.redraw()
def animate_interactive(data, t=None, dim_order=(0, 1, 2), fps=10.0, title='', xlabel='x', ylabel='y', font_size=24, color_bar=0, colorbar_label=None, sloppy=True, fancy=False, range_min=None, range_max=None, extent=[-1, 1, -1, 1], shade=False, azdeg=0, altdeg=65, arrowsX=None, arrowsY=None, arrows_res=10, arrows_pivot='mid', arrows_width=0.002, arrows_scale=5, arrows_color='black', plot_arrows_grid=False, movie_file=None, bitrate=1800, keep_images=False, figsize=(8, 7), dpi=300, **kwimshow): """ Assemble a 2D animation from a 3D array. call signature:: animate_interactive(data, t=None, dim_order=(0, 1, 2), fps=10.0, title='', xlabel='x', ylabel='y', font_size=24, color_bar=0, colorbar_label=None, sloppy=True, fancy=False, range_min=None, range_max=None, extent=[-1, 1, -1, 1], shade=False, azdeg=0, altdeg=65, arrowsX=None, arrowsY=None, arrows_res=10, arrows_pivot='mid', arrows_width=0.002, arrows_scale=5, arrows_color='black', plot_arrows_grid=False, movie_file=None, bitrate=1800, keep_images=False, figsize=(8, 7), dpi=300, **kwimshow) Assemble a 2D animation from a 3D array. *data* has to be a 3D array of shape [nt, nx, ny] and who's time index has the same dimension as *t*. The time index of *data* as well as its x and y indices can be changed via *dim_order*. Keyword arguments: *dim_order*: Ordering of the dimensions in the data array (t, x, y). *fps*: Frames per second of the animation. *title*: Title of the plot. *xlabel*: Label of the x-axis. *ylabel*: Label of the y-axis. *font_size*: Font size of the title, x and y label. The size of the x- and y-ticks is 0.7*font_size and the colorbar ticks' font size is 0.5*font_size. *color_bar*: [ 0 | 1 ] Determines how the colorbar changes: (0 - no cahnge; 1 - adapt extreme values). *colorbar_label*: Label of the color bar. *sloppy*: [ True | False ] If True the update of the plot lags one frame behind. This speeds up the plotting. *fancy*: [ True | False ] Use fancy font style. *range_min*, *range_max*: Range of the colortable. *extent*: [ None | (left, right, bottom, top) ] Limits for the axes (domain). *shade*: [ False | True ] If True plot a shaded relief instead of the usual colormap. Note that with this option cmap has to be specified like cmap = plt.cm.hot instead of cmap = 'hot'. Shading cannot be used with the color_bar = 0 option. *azdeg*, *altdeg*: Azimuth and altitude of the light source for the shading. *arrowsX*: Data containing the x-component of the arrows. *arrowsY*: Data containing the y-component of the arrows. *arrows_res*: Plot every arrows_res arrow. *arrows_pivot*: [ 'tail' | 'middle' | 'tip' ] The part of the arrow that is used as pivot point. *arrows_width*: Width of the arrows. *arrows_scale*: Scaling of the arrows. *arrows_color*: Color of the arrows. *plot_arrows_grid*: [ False | True ] If 'True' the grid where the arrows are aligned to is shown. *movie_file*: [ None | string ] The movie file where the animation should be saved to. If 'None' no movie file is written. Requires 'ffmpeg' to be installed. *bitrate*: Bitrate of the movie file. Set to higher value for higher quality. *keep_images*: [ False | True ] If 'True' the images for the movie creation are not deleted. *figsize*: Size of the figure in inches. *dpi*: Dots per inch of the frame. **kwimshow: Remaining arguments are identical to those of pylab.imshow. Refer to that help. """ try: import thread except: import _thread as thread global time_step, time_slider, pause global fig, axes, image, colorbar, arrows, manager, n_times, movie_files global rgb, plot_arrows def plot_frame(): """ Plot the current frame. """ global time_step, axes, axes, colorbar, arrows, manager, rgb if not movie_file is None: axes.set_title(title + r'$\quad$' + r'$t={0:.4e}$'.format(t[time_step]), fontsize=font_size) if not shade: image.set_data(data[time_step, :, :]) else: image.set_data(rgb[time_step, :, :, :]) if color_bar == 0: pass if color_bar == 1: colorbar.set_clim(vmin=data[time_step, :, :].min(), vmax=data[time_step, :, :].max()) colorbar.draw_all() if plot_arrows: arrows.set_UVC(U=arrowsX[time_step, ::arrows_res, ::arrows_res], V=arrowsY[time_step, ::arrows_res, ::arrows_res]) if not sloppy or (not movie_file is None): manager.canvas.draw() def play(thread_name): """ Play the movie. """ import time global time_step, time_slider, pause, fig, axes, n_times, movie_files pause = False while (time_step < n_times) and (not pause): # Write the image files for the movie. if not movie_file is None: plot_frame() frame_name = '{0}{1:06}.png'.format(movie_file, time_step) fig.savefig(frame_name, dpi=dpi) movie_files.append(frame_name) else: time_start = time.clock() time_slider.set_val(t[time_step]) # Wait for the next frame (fps). while (time.clock() - time_start < 1.0 / fps): pass time_step += 1 time_step -= 1 def play_thread(event): """ Call the play function as a separate thread (for GUI). """ global pause if pause: try: thread.start_new_thread(play, ("play_thread", )) except: print("Error: unable to start play thread.") def pausing(event): global pause print('pause') pause = True def reverse(event): global time_step, time_slider print('reverse') time_step -= 1 if time_step < 0: time_step = 0 # Plot the frame and update the time slider. time_slider.set_val(t[time_step]) def forward(event): global time_step, time_slider print('forward') time_step += 1 if time_step > len(t) - 1: time_step = len(t) - 1 # Plot the frame and update the time slider. time_slider.set_val(t[time_step]) import numpy as np import pylab as plt pause = True plot_arrows = False # Check if the data has the right dimensions. if (data.ndim != 3 and data.ndim != 4): print("Error: data dimensions are invalid: {0} instead of 3.".format( data.ndim)) return -1 # Transpose the data according to dim_order. unordered_data = data data = np.transpose(unordered_data, dim_order) del (unordered_data) # Check if arrows should be plotted. if not (arrowsX is None) and not (arrowsY is None): if (isinstance(arrowsX, np.ndarray) and isinstance(arrowsY, np.ndarray)): if arrowsX.ndim == 3: # Transpose the data according to dim_order. unordered_data = arrowsX arrowsX = np.transpose(unordered_data, dim_order) del (unordered_data) if arrowsY.ndim == 3: # Transpose the data according to dim_order. unordered_data = arrowsY arrowsY = np.transpose(unordered_data, dim_order) unordered_data = [] # Check if the dimensions of the arrow arrays match each other. if arrowsX.shape != arrowsY.shape: print( "Error: dimensions of arrowX do not match with dimensions of arrowY." ) return -1 else: plot_arrows = True else: print("Warning: arrowsX and/or arrowsY are of invalid type.") # Check if time array has the right length. n_times = len(t) if n_times != data.shape[0]: print( "Error: length of time array does not match length of data array.") return -1 if plot_arrows: if (n_times != arrowsX.shape[0]) or (n_times != arrowsY.shape[0]): print( "error: length of time array does not match length of arrows array." ) return -1 # Check if fps is positive. if fps < 0: print("Error: fps is not positive, fps = {0}.".format(fps)) return -1 # Determine the size of the data array. nX = data.shape[1] nY = data.shape[2] # Determine the minimum and maximum values of the data set. if not (range_min): range_min = np.min(data) if not (range_max): range_max = np.max(data) # Setup the plot. if fancy: plt.rc('text', usetex=True) plt.rc('font', family='arial') else: plt.rc('text', usetex=False) plt.rc('font', family='sans') if not movie_file is None: fig = plt.figure(figsize=figsize) axes = plt.axes([0.15, 0.1, .70, .85]) else: fig = plt.figure(figsize=figsize) axes = plt.axes([0.1, 0.3, .85, .65]) axes.set_title(title, fontsize=font_size) axes.set_xlabel(xlabel, fontsize=font_size) axes.set_ylabel(ylabel, fontsize=font_size) plt.xticks(fontsize=0.7 * font_size) plt.yticks(fontsize=0.7 * font_size) if shade: plane = np.zeros([nX, nY, 3]) else: plane = np.zeros([nX, nY]) # Apply shading. if shade: from matplotlib.colors import LightSource ls = LightSource(azdeg=azdeg, altdeg=altdeg) rgb = [] # Shading can be only used with color_bar=1 or color_bar=2 at the moment. if color_bar == 0: color_bar = 1 # Check if colormap is set, if not set it to 'copper'. if 'cmap' not in kwimshow.keys(): kwimshow['cmap'] = plt.cm.copper for i in range(data.shape[0]): tmp = ls.shade(data[i, :, :], kwimshow['cmap']) rgb.append(tmp.tolist()) rgb = np.array(rgb) del (tmp) # Calibrate the displayed colors for the data range. image = axes.imshow(plane, vmin=range_min, vmax=range_max, origin='lower', extent=extent, **kwimshow) colorbar = fig.colorbar(image) colorbar.set_label(colorbar_label, fontsize=font_size, labelpad=10) # Change the font size of the colorbar's ytickslabels. cbytick_obj = plt.getp(colorbar.ax.axes, 'yticklabels') plt.setp(cbytick_obj, fontsize=0.5 * font_size) # Plot the arrows. if plot_arrows: # Prepare the mesh grid where the arrows will be drawn. arrow_grid = np.meshgrid( np.arange( extent[0], extent[1], float(extent[1] - extent[0]) * arrows_res / (data.shape[2] - 1)), np.arange( extent[2], extent[3], float(extent[3] - extent[2]) * arrows_res / (data.shape[1] - 1))) arrows = axes.quiver(arrow_grid[0], arrow_grid[1], arrowsX[0, ::arrows_res, ::arrows_res], arrowsY[0, ::arrows_res, ::arrows_res], units='width', pivot=arrows_pivot, width=arrows_width, scale=arrows_scale, color=arrows_color) # Plot the grid for the arrows. if plot_arrows_grid: axes.plot(arrow_grid[0], arrow_grid[1], 'k.') # For real-time image display. if (not sloppy) or (not movie_file is None): manager = plt.get_current_fig_manager() manager.show() time_step = 0 if not movie_file is None: import os movie_files = [] # Start the animation. play('no_thread') # Write the movie file. ffmpeg_command = "ffmpeg -r {0} -i {1}%6d.png -vcodec mpeg4 -b:v {2} -q:v 0 {3}.avi".format( fps, movie_file, bitrate, movie_file) os.system(ffmpeg_command) # Clean up the image files. if not keep_images: print("Cleaning up files.") for fname in movie_files: os.remove(fname) else: # Set up the gui. plt.ion() plt.subplots_adjust(bottom=0.2) axes_play = plt.axes([0.1, 0.05, 0.15, 0.05]) button_play = plt.Button(axes_play, 'play', color='lightgoldenrodyellow', hovercolor='0.975') button_play.on_clicked(play_thread) axes_pause = plt.axes([0.3, 0.05, 0.15, 0.05]) button_pause = plt.Button(axes_pause, 'pause', color='lightgoldenrodyellow', hovercolor='0.975') button_pause.on_clicked(pausing) axes_reverse = plt.axes([0.5, 0.05, 0.15, 0.05]) button_reverse = plt.Button(axes_reverse, 'reverse', color='lightgoldenrodyellow', hovercolor='0.975') button_reverse.on_clicked(reverse) axes_forward = plt.axes([0.7, 0.05, 0.15, 0.05]) button_forward = plt.Button(axes_forward, 'forward', color='lightgoldenrodyellow', hovercolor='0.975') button_forward.on_clicked(forward) # Create the time slider. time_slider_axes = plt.axes([0.2, 0.12, 0.6, 0.03], facecolor='lightgoldenrodyellow') time_slider = plt.Slider(time_slider_axes, 'time', t[0], t[-1], valinit=t[0]) def update(val): global time_step # Find the closest time step to the slider time value. for i in range(len(t)): if t[i] < time_slider.val: time_step = i if (time_step != len(t) - 1): if (t[time_step + 1] - time_slider.val) < (time_slider.val - t[time_step]): time_step += 1 plot_frame() time_slider.on_changed(update) plt.show() print("done")
def plot_hillshade(data_grd): import numpy as np import matplotlib.pyplot as plt from matplotlib.cbook import get_sample_data from matplotlib.colors import LightSource from src.xovutil.gtrack2dem import import_dem from examples.MLA.options import tmpdir with import_dem( data_grd ) as dem: # np.load(get_sample_data('jacksboro_fault_dem.npz')) as dem: # print(dem.data[0].shape) xrange = [2000, 4000] yrange = [500, 2500] z = dem.data[0][xrange[0]:xrange[1], yrange[0]:yrange[1]] # z = dem['elevation'] # -- Optional dx and dy for accurate vertical exaggeration ---------------- # If you need topographically accurate vertical exaggeration, or you don't # want to guess at what *vert_exag* should be, you'll need to specify the # cellsize of the grid (i.e. the *dx* and *dy* parameters). Otherwise, any # *vert_exag* value you specify will be relative to the grid spacing of # your input data (in other words, *dx* and *dy* default to 1.0, and # *vert_exag* is calculated relative to those parameters). Similarly, *dx* # and *dy* are assumed to be in the same units as your input z-values. # Therefore, we'll need to convert the given dx and dy from decimal degrees # to meters. dx, dy = 1, 1 # dem['dx'], dem['dy'] dy = 111200 * dy dx = 111200 * dx * np.cos(np.radians(-1500.)) # dem['ymin'])) # ------------------------------------------------------------------------- # choose vert_exag vert_exag = [100, 1000, 10000] # Shade from the northwest, with the sun 45 degrees from horizontal ls = LightSource(azdeg=315, altdeg=5) cmap = plt.cm.gist_earth fig, axes = plt.subplots(nrows=4, ncols=3, figsize=(8, 9)) plt.setp(axes.flat, xticks=[], yticks=[]) # Vary vertical exaggeration and blend mode and plot all combinations for col, ve in zip(axes.T, vert_exag): # Show the hillshade intensity image in the first row col[0].imshow(ls.hillshade(z, vert_exag=ve, dx=dx, dy=dy), cmap='gray') # Place hillshaded plots with different blend modes in the rest of the rows for ax, mode in zip(col[1:], ['hsv', 'overlay', 'soft']): rgb = ls.shade(z, cmap=cmap, blend_mode=mode, vert_exag=ve, dx=dx, dy=dy) ax.imshow(rgb) # Label rows and columns for ax, ve in zip(axes[0], vert_exag): ax.set_title('{0}'.format(ve), size=18) for ax, mode in zip(axes[:, 0], ['Hillshade', 'hsv', 'overlay', 'soft']): ax.set_ylabel(mode, size=18) # Group labels... axes[0, 1].annotate('Vertical Exaggeration', (0.5, 1), xytext=(0, 30), textcoords='offset points', xycoords='axes fraction', ha='center', va='bottom', size=20) axes[2, 0].annotate('Blend Mode', (0, 0.5), xytext=(-30, 0), textcoords='offset points', xycoords='axes fraction', ha='right', va='center', size=20, rotation=90) fig.subplots_adjust(bottom=0.05, right=0.95) plt.savefig(tmpdir + "test_hillshade.png") return True
def draw_3d(self): """ Draw various 3D plots """ self.init_axes() bb = fb.fil[0]['ba'][0] aa = fb.fil[0]['ba'][1] zz = np.array(fb.fil[0]['zpk'][0]) pp = np.array(fb.fil[0]['zpk'][1]) wholeF = fb.fil[0]['freqSpecsRangeType'] != 'half' # not used f_S = fb.fil[0]['f_S'] N_FFT = params['N_FFT'] alpha = self.diaAlpha.value()/10. cmap = cm.get_cmap(str(self.cmbColormap.currentText())) # Number of Lines /step size for H(f) stride, mesh, contour3d: stride = 10 - self.diaHatch.value() NL = 3 * self.diaHatch.value() + 5 surf_enabled = qget_cmb_box(self.cmbMode3D, data=False) in {'Surf', 'Contour'} self.cmbColormap.setEnabled(surf_enabled) self.chkColormap_r.setEnabled(surf_enabled) self.chkLighting.setEnabled(surf_enabled) self.chkColBar.setEnabled(surf_enabled) self.diaAlpha.setEnabled(surf_enabled or self.chkContour2D.isChecked()) #cNorm = colors.Normalize(vmin=0, vmax=values[-1]) #scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet) #----------------------------------------------------------------------------- # Calculate H(w) along the upper half of unity circle #----------------------------------------------------------------------------- [w, H] = sig.freqz(bb, aa, worN=N_FFT, whole=True) H = np.nan_to_num(H) # replace nans and inf by finite numbers H_abs = abs(H) H_max = max(H_abs) H_min = min(H_abs) #f = w / (2 * pi) * f_S # translate w to absolute frequencies #F_min = f[np.argmin(H_abs)] plevel_rel = 1.05 # height of plotted pole position relative to zmax zlevel_rel = 0.1 # height of plotted zero position relative to zmax if self.chkLog.isChecked(): # logarithmic scale bottom = np.floor(max(self.zmin_dB, 20*log10(H_min)) / 10) * 10 top = self.zmax_dB top_bottom = top - bottom zlevel = bottom - top_bottom * zlevel_rel if self.cmbMode3D.currentText() == 'None': # "Poleposition" for H(f) plot only plevel_top = 2 * bottom - zlevel # height of displayed pole position plevel_btm = bottom else: plevel_top = top + top_bottom * (plevel_rel - 1) plevel_btm = top else: # linear scale bottom = max(self.zmin, H_min) # min. display value top = self.zmax # max. display value top_bottom = top - bottom # top = zmax_rel * H_max # calculate display top from max. of H(f) zlevel = bottom + top_bottom * zlevel_rel # height of displayed zero position if self.cmbMode3D.currentText() == 'None': # "Poleposition" for H(f) plot only #H_max = np.clip(max(H_abs), 0, self.zmax) # make height of displayed poles same to zeros plevel_top = bottom + top_bottom * zlevel_rel plevel_btm = bottom else: plevel_top = plevel_rel * top plevel_btm = top # calculate H(jw)| along the unity circle and |H(z)|, each clipped # between bottom and top H_UC = H_mag(bb, aa, self.xy_UC, top, H_min=bottom, log=self.chkLog.isChecked()) Hmag = H_mag(bb, aa, self.z, top, H_min=bottom, log=self.chkLog.isChecked()) #=============================================================== ## plot Unit Circle (UC) #=============================================================== if self.chkUC.isChecked(): # Plot unit circle and marker at (1,0): self.ax3d.plot(self.xy_UC.real, self.xy_UC.imag, ones(len(self.xy_UC)) * bottom, lw=2, color='k') self.ax3d.plot([0.97, 1.03], [0, 0], [bottom, bottom], lw=2, color='k') #=============================================================== ## plot ||H(f)| along unit circle as 3D-lineplot #=============================================================== if self.chkHf.isChecked(): self.ax3d.plot(self.xy_UC.real, self.xy_UC.imag, H_UC, alpha = 0.5) # draw once more as dashed white line to improve visibility self.ax3d.plot(self.xy_UC.real, self.xy_UC.imag, H_UC, 'w--') if stride < 10: # plot thin vertical line every stride points on the UC for k in range(len(self.xy_UC[::stride])): self.ax3d.plot([self.xy_UC.real[::stride][k], self.xy_UC.real[::stride][k]], [self.xy_UC.imag[::stride][k], self.xy_UC.imag[::stride][k]], [np.ones(len(self.xy_UC[::stride]))[k]*bottom, H_UC[::stride][k]], linewidth=1, color=(0.5, 0.5, 0.5)) #=============================================================== ## plot Poles and Zeros #=============================================================== if self.chkPZ.isChecked(): PN_SIZE = 8 # size of P/N symbols # Plot zero markers at |H(z_i)| = zlevel with "stems": self.ax3d.plot(zz.real, zz.imag, ones(len(zz)) * zlevel, 'o', markersize=PN_SIZE, markeredgecolor='blue', markeredgewidth=2.0, markerfacecolor='none') for k in range(len(zz)): # plot zero "stems" self.ax3d.plot([zz[k].real, zz[k].real], [zz[k].imag, zz[k].imag], [bottom, zlevel], linewidth=1, color='b') # Plot the poles at |H(z_p)| = plevel with "stems": self.ax3d.plot(np.real(pp), np.imag(pp), plevel_top, 'x', markersize=PN_SIZE, markeredgewidth=2.0, markeredgecolor='red') for k in range(len(pp)): # plot pole "stems" self.ax3d.plot([pp[k].real, pp[k].real], [pp[k].imag, pp[k].imag], [plevel_btm, plevel_top], linewidth=1, color='r') #=============================================================== ## 3D-Plots of |H(z)| clipped between |H(z)| = top #=============================================================== m_cb = cm.ScalarMappable(cmap=cmap) # normalized proxy object that is mappable m_cb.set_array(Hmag) # for colorbar #--------------------------------------------------------------- ## 3D-mesh plot #--------------------------------------------------------------- if self.cmbMode3D.currentText() == 'Mesh': # fig_mlab = mlab.figure(fgcolor=(0., 0., 0.), bgcolor=(1, 1, 1)) # self.ax3d.set_zlim(0,2) self.ax3d.plot_wireframe(self.x, self.y, Hmag, rstride=5, cstride=stride, linewidth=1, color='gray') #--------------------------------------------------------------- ## 3D-surface plot #--------------------------------------------------------------- # http://stackoverflow.com/questions/28232879/phong-shading-for-shiny-python-3d-surface-plots elif self.cmbMode3D.currentText() == 'Surf': if MLAB: ## Mayavi surf = mlab.surf(self.x, self.y, H_mag, colormap='RdYlBu', warp_scale='auto') # Change the visualization parameters. surf.actor.property.interpolation = 'phong' surf.actor.property.specular = 0.1 surf.actor.property.specular_power = 5 # s = mlab.contour_surf(self.x, self.y, Hmag, contour_z=0) mlab.show() else: if self.chkLighting.isChecked(): ls = LightSource(azdeg=0, altdeg=65) # Create light source object rgb = ls.shade(Hmag, cmap=cmap) # Shade data, creating an rgb array cmap_surf = None else: rgb = None cmap_surf = cmap # s = self.ax3d.plot_surface(self.x, self.y, Hmag, # alpha=OPT_3D_ALPHA, rstride=1, cstride=1, cmap=cmap, # linewidth=0, antialiased=False, shade=True, facecolors = rgb) # s.set_edgecolor('gray') s = self.ax3d.plot_surface(self.x, self.y, Hmag, alpha=alpha, rstride=1, cstride=1, linewidth=0, antialiased=False, facecolors=rgb, cmap=cmap_surf, shade=True) s.set_edgecolor(None) #--------------------------------------------------------------- ## 3D-Contour plot #--------------------------------------------------------------- elif self.cmbMode3D.currentText() == 'Contour': s = self.ax3d.contourf3D(self.x, self.y, Hmag, NL, alpha=alpha, cmap=cmap) #--------------------------------------------------------------- ## 2D-Contour plot # TODO: 2D contour plots do not plot correctly together with 3D plots in # current matplotlib 1.4.3 -> disable them for now # TODO: zdir = x / y delivers unexpected results -> rather plot max(H) # along the other axis? # TODO: colormap is created depending on the zdir = 'z' contour plot # -> set limits of (all) other plots manually? if self.chkContour2D.isChecked(): # self.ax3d.contourf(x, y, Hmag, 20, zdir='x', offset=xmin, # cmap=cmap, alpha = alpha)#, vmin = bottom)#, vmax = top, vmin = bottom) # self.ax3d.contourf(x, y, Hmag, 20, zdir='y', offset=ymax, # cmap=cmap, alpha = alpha)#, vmin = bottom)#, vmax = top, vmin = bottom) s = self.ax3d.contourf(self.x, self.y, Hmag, NL, zdir='z', offset=bottom - (top - bottom) * 0.05, cmap=cmap, alpha=alpha) # plot colorbar for suitable plot modes if self.chkColBar.isChecked() and (self.chkContour2D.isChecked() or str(self.cmbMode3D.currentText()) in {'Contour', 'Surf'}): self.colb = self.mplwidget.fig.colorbar(m_cb, ax=self.ax3d, shrink=0.8, aspect=20, pad=0.02, fraction=0.08) #---------------------------------------------------------------------- ## Set view limits and labels #---------------------------------------------------------------------- if not self.mplwidget.mplToolbar.a_lk.isChecked(): self.ax3d.set_xlim3d(self.xmin, self.xmax) self.ax3d.set_ylim3d(self.ymin, self.ymax) self.ax3d.set_zlim3d(bottom, top) else: self._restore_axes() self.ax3d.set_xlabel('Re')#(fb.fil[0]['plt_fLabel']) self.ax3d.set_ylabel('Im') #(r'$ \tau_g(\mathrm{e}^{\mathrm{j} \Omega}) / T_S \; \rightarrow $') # self.ax3d.set_zlabel(r'$|H(z)|\; \rightarrow $') self.ax3d.set_title(r'3D-Plot of $|H(\mathrm{e}^{\mathrm{j} \Omega})|$ and $|H(z)|$') self.redraw()
def mcw_pls_cv(self,ncomp_range=range(1,21),sig_start=0.1,optimization="grid", plot=False,verbose=True, osc_params=(10,1)): # Separating X from Y for PLS # Needs to be converted to numpy array from pandas df X=self.df[self.freqs].to_numpy() # Y need to be converted to numpy array from pandas series and reshaped to (N,1) from (N,) Y=self.df[self.y_name].to_numpy().reshape(-1, 1) sample_std=np.std(self.df[self.y_name]) # CV based on measurement day if self.cval=="MD": cv = LeaveOneGroupOut() folds=list(cv.split(X=X,y=Y,groups=self.df[self.date_name])) # kfold CV elif self.cval=="kfold": cv = KFold(n_splits=self.cval_param) folds=list(cv.split(X)) else: raise InputError("Invalid CV type!") if optimization=="grid": # Create a search vector from starting values for gridsearch sig_list=np.linspace(sig_start/10,sig_start*10,30) rpd_best_all=0 non_improve=0 repeat=True while repeat: # Array for storing CV errors cv_RMSE_all=np.zeros([len(folds),len(ncomp_range),len(sig_list)]) i=0 for train,val in folds: # If OSC model specified if len(osc_params)==2: osc=OSC(nicomp=osc_params[0],ncomp=osc_params[1]) osc.fit(X[train], Y[train]) X_train_osc=osc.X_osc X_val_osc=osc.transform(X[val]) j=0 for ncomp in ncomp_range: k=0 for sig in sig_list: if len(osc_params)==2: pls = mcw_pls_sklearn(n_components=ncomp, max_iter=30, R_initial=None, scale_sigma2=sig) pls.fit(X_train_osc, Y[train]) cv_RMSE_all[i,j,k]=metrics.mean_squared_error( Y[val], pls.predict(X_val_osc))**0.5 else: pls = mcw_pls_sklearn(n_components=ncomp, max_iter=30, R_initial=None, scale_sigma2=sig) pls.fit(X[train], Y[train]) cv_RMSE_all[i,j,k]=metrics.mean_squared_error( Y[val], pls.predict(X[val]))**0.5 k=k+1 j=j+1 i=i+1 cv_RMSE_ncomp_sigs=np.mean(cv_RMSE_all,axis=0) # Best model ncomp_best=ncomp_range[np.where( cv_RMSE_ncomp_sigs==np.amin(cv_RMSE_ncomp_sigs))[0][0]] sig_best=sig_list[np.where( cv_RMSE_ncomp_sigs==np.amin(cv_RMSE_ncomp_sigs))[1][0]] rpd_best=sample_std/np.amin(cv_RMSE_ncomp_sigs) if verbose: print("Best RMSE: ",np.amin(cv_RMSE_ncomp_sigs)) print("Best RPD: ",rpd_best) print("Number of latent components: ",ncomp_best) print("Best sigma: ",sig_best) # Check against all time best if rpd_best>rpd_best_all: ncomp_best_all = ncomp_best sig_best_all = sig_best rpd_best_all= rpd_best else: # Increase counter if there is no improvement non_improve=non_improve+1 repeat=False # Check if best value is in IQ range if sig_best<np.quantile(sig_list,0.2) or sig_best>np.quantile(sig_list,0.8): # If not, move the search interval based on the magnitude of the best value scale=math.floor(math.log10(sig_best))-1 lower=sig_best-(10**scale)*5 upper=sig_best+(10**scale)*5 # If best value is at the extreme of the interval expand it by a lot that way if min(sig_list)==sig_best: lower=sig_best/2 elif max(sig_list)==sig_best: upper=sig_best*2 # Create new search vector sig_list=np.linspace(lower,upper,10) # Repeat evaluation repeat=True # Terminate early if no improvements in 10 iterations if non_improve>10: repeat=False print("No improvement, terminate early.") if repeat: print("new iteration") # Set final values to all time best ncomp_best=ncomp_best_all sig_best=sig_best_all rpd_best=rpd_best_all elif optimization=="simple": # Array for storing CV errors sig_list=sig_start cv_RMSE_all=np.zeros([len(folds),len(ncomp_range),len(sig_list)]) i=0 for ncomp in ncomp_range: j=0 for sig in sig_list: pls = mcw_pls_sklearn(n_components=ncomp, max_iter=30, R_initial=None, scale_sigma2=sig) k=0 for train,val in folds: pls.fit(X[train], Y[train]) cv_RMSE_all[k,i,j]=metrics.mean_squared_error( Y[val], pls.predict(X[val]))**0.5 k=k+1 j=j+1 i=i+1 # Printing and plotting CV results cv_RMSE_ncomp_sigs=np.mean(cv_RMSE_all,axis=0) if plot: cv_RPD_ncomp_sigs=sample_std/cv_RMSE_ncomp_sigs fig = plt.figure(figsize=(10,5)) ax = plt.axes(projection="3d") # Cartesian indexing (x,y) transposes matrix indexing (i,j) x, y = np.meshgrid(list(sig_list),list(ncomp_range)) z=cv_RPD_ncomp_sigs ls = LightSource(270, 45) rgb = ls.shade(z, cmap=cm.gist_earth, vert_exag=0.1, blend_mode='soft') surf = ax.plot_surface(x, y, z, rstride=1, cstride=1, facecolors=rgb, linewidth=0, antialiased=False, shade=False) plt.show() # Best model ncomp_best=ncomp_range[np.where( cv_RMSE_ncomp_sigs==np.amin(cv_RMSE_ncomp_sigs))[0][0]] sig_best=sig_list[np.where( cv_RMSE_ncomp_sigs==np.amin(cv_RMSE_ncomp_sigs))[1][0]] rpd_best=sample_std/np.amin(cv_RMSE_ncomp_sigs) print("Best RMSE: ",np.amin(cv_RMSE_ncomp_sigs)) print("Best RPD: ",rpd_best) print("Number of latent components: ",ncomp_best) print("Best sigma: ",sig_best) return (ncomp_best,sig_best,rpd_best)
def osc_cv(self,nicomp_range=range(10,130,10),ncomp_range=range(1,5),epsilon = 10e-6, max_iters = 20,model="pls",model_parameter_range=range(1,11)): # Separating X from Y for PLS # Needs to be converted to numpy array from pandas df X=self.df[self.freqs].to_numpy() # Y need to be converted to numpy array from pandas series and reshaped to (N,1) from (N,) Y=self.df[self.y_name].to_numpy().reshape(-1, 1) # CV based on measurement day if self.cval=="MD": cv = LeaveOneGroupOut() folds=list(cv.split(X=X,y=Y,groups=self.df[self.date_name])) # kfold CV elif self.cval=="kfold": cv = KFold(n_splits=self.cval_param) folds=list(cv.split(X)) else: raise InputError("Invalid CV type!") #Matrix for cv values for all the possible parameter combinations cv_RMSE_all=np.zeros([len(folds),len(model_parameter_range),len(nicomp_range),len(ncomp_range)]) i=0 #possible internal component values for osc for nicomp in nicomp_range: j=0 #possible removed component values for osc for ncomp in ncomp_range: k=0 for train, val in folds: # train osc osc_obj=OSC("SWosc",nicomp,ncomp,epsilon, max_iters) X_osc_train, W,P,mu_x=osc_obj.fit(X[train],Y[train]) # apply osc on validation set # mean center data, alternatively the training set's mean can be used # if you think it is a better estimate by mean="training" X_osc_val=osc_obj.transform(X[val],mean="estimate") l=0 #possible model patrameter values for pls for param in model_parameter_range: #setup pls model pls = PLSRegression(param,scale=False) #train pls pls.fit(X_osc_train, Y[train]) #predict with pls and calculate error cv_RMSE_all[k,l,i,j]=metrics.mean_squared_error( Y[val], pls.predict(X_osc_val))**0.5 l=l+1 k=k+1 j=j+1 i=i+1 # Calculate mean performance across the folds cv_RMSE_mean=np.mean(cv_RMSE_all,axis=0) # Find maximum for every osc paremeter combination cv_RMSE=np.amax(cv_RMSE_mean, axis=0) cv_RPD=np.std(self.df[self.y_name])/cv_RMSE fig = plt.figure(figsize=(10,5)) ax = plt.axes(projection="3d") # Cartesian indexing (x,y) transposes matrix indexing (i,j) x, y = np.meshgrid(list(ncomp_range),list(nicomp_range)) z=cv_RPD ls = LightSource(200, 45) rgb = ls.shade(z, cmap=cm.gist_earth, vert_exag=0.1, blend_mode='soft') surf = ax.plot_surface(x, y, z, rstride=1, cstride=1, facecolors=rgb, linewidth=0, antialiased=False, shade=False) plt.show() # Best model print("Best RMSE: ",np.amin(cv_RMSE)) print("Best RPD: ",np.std(self.df[self.y_name])/np.amin(cv_RMSE)) print("Number of internal components: ",nicomp_range[np.where( cv_RMSE==np.amin(cv_RMSE))[0][0]]) print("Number of removed components: ",ncomp_range[np.where( cv_RMSE==np.amin(cv_RMSE))[1][0]]) return cv_RMSE
def __init__(self, sigma, fraction=0.5): self.gauss_filter = GaussianFilter(sigma, alpha=1) self.light_source = LightSource() self.fraction = fraction
X, Y = np.meshgrid(xa, ya) plt.figure() plt.imshow(pol[:,:,0], interpolation='nearest') plt.colorbar() plt.savefig('policy_no_use',dpi=600) plt.show() plt.figure() plt.imshow(pol[:,:,1], interpolation='nearest') plt.colorbar() plt.savefig('policy_use',dpi=600) plt.show() fig = plt.figure() ls = LightSource(270, 45) # To use a custom hillshading mode, override the built-in shading and pass # in the rgb colors of the shaded surface calculated from "shade". rgb = ls.shade(v_actions[:,:,0].T, cmap=cm.gist_earth, vert_exag=0.1, blend_mode='soft') ax = fig.gca(projection='3d') ax.plot_surface(X, Y, v_actions[:,:,0].T, rstride=1, cstride=1, facecolors=rgb, linewidth=0, antialiased=False, shade=False) plt.savefig('value_no_use',dpi=600) plt.show() fig = plt.figure() ls = LightSource(270, 45) # To use a custom hillshading mode, override the built-in shading and pass # in the rgb colors of the shaded surface calculated from "shade". rgb = ls.shade(v_actions[:,:,1].T, cmap=cm.gist_earth, vert_exag=0.1, blend_mode='soft') ax = fig.gca(projection='3d')
#-- Optional dx and dy for accurate vertical exaggeration -------------------- # If you need topographically accurate vertical exaggeration, or you don't want # to guess at what *vert_exag* should be, you'll need to specify the cellsize # of the grid (i.e. the *dx* and *dy* parameters). Otherwise, any *vert_exag* # value you specify will be realitive to the grid spacing of your input data # (in other words, *dx* and *dy* default to 1.0, and *vert_exag* is calculated # relative to those parameters). Similarly, *dx* and *dy* are assumed to be in # the same units as your input z-values. Therefore, we'll need to convert the # given dx and dy from decimal degrees to meters. dx, dy = dem['dx'], dem['dy'] dy = 111200 * dy dx = 111200 * dx * np.cos(np.radians(dem['ymin'])) #----------------------------------------------------------------------------- # Shade from the northwest, with the sun 45 degrees from horizontal ls = LightSource(azdeg=315, altdeg=45) cmap = plt.cm.gist_earth fig, axes = plt.subplots(nrows=4, ncols=3, figsize=(8, 9)) plt.setp(axes.flat, xticks=[], yticks=[]) # Vary vertical exaggeration and blend mode and plot all combinations for col, ve in zip(axes.T, [0.1, 1, 10]): # Show the hillshade intensity image in the first row col[0].imshow(ls.hillshade(z, vert_exag=ve, dx=dx, dy=dy), cmap='gray') # Place hillshaded plots with different blend modes in the rest of the rows for ax, mode in zip(col[1:], ['hsv', 'overlay', 'soft']): rgb = ls.shade(z, cmap=cmap, blend_mode=mode, vert_exag=ve, dx=dx, dy=dy) ax.imshow(rgb)
def plot(self, runid, datatype, period, width=-1., use_mask_all = False, semfactor=2., Nthresh=None, clabel='', cmap='surf',\ projection='lambert', hillshade = False, vmin = None, vmax = None, showfig = True, v_rel = None): """plot maps from the tomographic inversion ================================================================================================================= ::: input parameters ::: runid - id of run datatype - datatype for plotting period - period of data sem_factor - factor multiplied to get the finalized uncertainties clabel - label of colorbar cmap - colormap projection - projection type vmin, vmax - min/max value of plotting showfig - show figure or not ================================================================================================================= """ dataid = 'tomo_stack_'+str(runid) ingroup = self[dataid] pers = self.attrs['period_array'] self._get_lon_lat_arr() if not period in pers: raise KeyError('!!! period = '+str(period)+' not included in the database') pergrp = ingroup['%g_sec'%( period )] if datatype == 'vel' or datatype=='velocity' or datatype == 'v': datatype = 'vel_iso' elif datatype == 'sem' or datatype == 'un' or datatype == 'uncertainty': datatype = 'vel_sem' elif datatype == 'std': datatype = 'slowness_std' try: data = pergrp[datatype][()] except: outstr = '' for key in pergrp.keys(): outstr +=key outstr +=', ' outstr = outstr[:-1] raise KeyError('Unexpected datatype: '+datatype+ ', available datatypes are: '+outstr) if datatype=='Nmeasure_aniso': factor = ingroup.attrs['grid_lon'] * ingroup.attrs['grid_lat'] else: factor = 1 if datatype=='Nmeasure_aniso' or datatype=='unpsi' or datatype=='unamp' or datatype=='amparr': mask = pergrp['mask_aniso'][()] + pergrp['mask'][()] else: mask = pergrp['mask'][()] if use_mask_all: mask = self.attrs['mask'] if not (Nthresh is None): Narr = pergrp['NmeasureQC'][()] mask += Narr < Nthresh if datatype == 'vel_sem': data *= 1000.*semfactor # smoothing if width > 0.: gridder = _grid_class.SphereGridder(minlon = self.minlon, maxlon = self.maxlon, dlon = self.dlon, \ minlat = self.minlat, maxlat = self.maxlat, dlat = self.dlat, period = period, \ evlo = 0., evla = 0., fieldtype = 'Tph', evid = 'plt') gridder.read_array(inlons = self.lonArr[np.logical_not(mask)], inlats = self.latArr[np.logical_not(mask)], inzarr = data[np.logical_not(mask)]) outfname = 'plt_Tph.lst' prefix = 'plt_Tph_' gridder.gauss_smoothing(workingdir = './temp_plt', outfname = outfname, width = width) data[:] = gridder.Zarr mdata = ma.masked_array(data/factor, mask=mask ) #----------- # plot data #----------- m = self._get_basemap(projection = projection) x, y = m(self.lonArr, self.latArr) try: import pycpt if os.path.isfile(cmap): cmap = pycpt.load.gmtColormap(cmap) # cmap = cmap.reversed() elif os.path.isfile(cpt_path+'/'+ cmap + '.cpt'): cmap = pycpt.load.gmtColormap(cpt_path+'/'+ cmap + '.cpt') cmap.set_bad('silver', alpha = 0.) except: pass ################################################################### # shapefname = '/home/lili/data_marin/map_data/geological_maps/qfaults' # m.readshapefile(shapefname, 'faultline', linewidth = 3, color='black') # m.readshapefile(shapefname, 'faultline', linewidth = 1.5, color='white') shapefname = '/home/lili/code/gem-global-active-faults/shapefile/gem_active_faults' # m.readshapefile(shapefname, 'faultline', linewidth = 4, color='black', default_encoding='windows-1252') if projection=='lambert': shapefname = '/home/lili/data_marin/map_data/geological_maps/qfaults' m.readshapefile(shapefname, 'faultline', linewidth = 3, color='black') m.readshapefile(shapefname, 'faultline', linewidth = 1.5, color='white') else: m.readshapefile(shapefname, 'faultline', linewidth = 2., color='grey', default_encoding='windows-1252') # shapefname = '/home/lili/data_mongo/fault_shp/doc-line' # # m.readshapefile(shapefname, 'faultline', linewidth = 4, color='black') # m.readshapefile(shapefname, 'faultline', linewidth = 2., color='grey') shapefname = '/home/lili/data_marin/map_data/volcano_locs/SDE_GLB_VOLC.shp' shplst = shapefile.Reader(shapefname) for rec in shplst.records(): lon_vol = rec[4] lat_vol = rec[3] xvol, yvol = m(lon_vol, lat_vol) m.plot(xvol, yvol, '^', mfc='white', mec='k', ms=10) ################################################################### if hillshade: from netCDF4 import Dataset from matplotlib.colors import LightSource import pycpt etopodata = Dataset('/home/lili/gebco_mongo.nc') etopo = (etopodata.variables['elevation'][:]).data lons = (etopodata.variables['lon'][:]).data lons[lons>180.] = lons[lons>180.] - 360. lats = (etopodata.variables['lat'][:]).data ls = LightSource(azdeg=315, altdeg=45) ny, nx = etopo.shape topodat,xtopo,ytopo = m.transform_scalar(etopo,lons,lats,nx, ny, returnxy=True) m.imshow(ls.hillshade(topodat, vert_exag=1., dx=1., dy=1.), cmap='gray') if v_rel is not None: mdata = (mdata - v_rel)/v_rel * 100. if hillshade: im = m.pcolormesh(x, y, mdata, cmap = cmap, shading = 'gouraud', vmin = vmin, vmax = vmax, alpha=.5) else: im = m.pcolormesh(x, y, mdata, cmap = cmap, shading = 'gouraud', vmin = vmin, vmax = vmax) m.fillcontinents(color='silver', lake_color='none',zorder=0.2, alpha=1.) m.drawcountries(linewidth=1.) # m.fillcontinents(color='none', lake_color='#99ffff',zorder=100., alpha=1.) # m.contour(x, y, mask_eik, colors='white', lw=1) # cb = m.colorbar(im, "bottom", size="3%", pad='2%', ticks=[10., 15., 20., 25., 30., 35., 40., 45., 50., 55., 60.]) # cb = m.colorbar(im, "bottom", size="3%", pad='2%', ticks=[20., 25., 30., 35., 40., 45., 50., 55., 60., 65., 70.]) # cb = m.colorbar(im, "bottom", size="5%", pad='2%', ticks=[4.0, 4.1, 4.2, 4.3, 4.4]) cb = m.colorbar(im, "bottom", size="5%", pad='2%') cb.set_label(clabel, fontsize=40, rotation=0) # cb.outline.set_linewidth(2) plt.suptitle(str(period)+' sec', fontsize=20) cb.ax.tick_params(labelsize = 20) print ('=== plotting data from '+dataid) if showfig: plt.show() return
'October', 'November', 'December'] day_cumsum = np.cumsum(day_per_month) files_per_day = 1 ############################################################################## # Set up plot ################################################################ ############################################################################## f, ax = plt.subplots(1, 1, figsize=(20, 10)) csfont = {'fontname': 'Ubuntu'} f.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=None, hspace=None) ls = LightSource(azdeg=315, altdeg=30) with Dataset(tracer_source, mode='r') as nc: # Check that there is enough data in the file if np.shape(nc.variables[sst_variable_name][:])[0] < total_frames: raise ValueError('total_frames exceeds number of frames in data!') sst = np.flipud(nc.variables[sst_variable_name][0, :, :]) sst = np.ma.masked_values(sst, 0) sst_im = ls.shade(sst, cmap=cmo.balance, blend_mode='soft', vert_exag=75, vmin=tmin, vmax=tmax) im = ax.imshow(sst_im, aspect='auto') ax.set_axis_off()
nans = np.logical_and(nan1213_1215, nan1315) nan_mask = np.ma.make_mask(nans) hv_snow_2012 = np.ma.masked_array(hv_snow['2012_std'], nan_mask) hv_snow_2013 = np.ma.masked_array(hv_snow['2013_std'], nan_mask) hv_snow_2015 = np.ma.masked_array(hv_snow['2015_std'], nan_mask) elevation_src = rasterio.open( '/home/cparr/Snow_Patterns/snow_data/happy_valley/raster/snow_free/dem/hv_2m_snowfree_dem_watermasked.tif' ) elevation = elevation_src.read(1) elevation = elevation[2000:6000] elevation = elevation[::, 140::] # elevation = np.ma.masked_less(elevation, 0, copy=True) elev = np.ma.masked_array(elevation, nan_mask) ls = LightSource(azdeg=280, altdeg=35) cmap = plt.cm.terrain rgb = ls.shade(elev, cmap=cmap, vert_exag=5, vmin=360, vmax=460, blend_mode='soft') #hv_snow_2012 = cv2.bilateralFilter(hv_snow_2012,3,15,15) #hv_snow_2013 = cv2.bilateralFilter(hv_snow_2013,3,15,15) #hv_snow_2015 = cv2.bilateralFilter(hv_snow_2015,3,15,15) ### ylabels = ['0', '2', '4', '6', '8']
def plot_shaded_map(ax=None, cmap='gist_earth',saveto=None): if ax is None: scale = 0.7 fig,ax = plt.subplots(figsize=(10*scale,10*scale)) # dtmfile = '/home/raul/Github/RadarQC/merged_dem_38-39_123-124_extended.tif' # dtmfile = '/home/raul/Dropbox/NOCAL_DEM/merged_dem_38-39_123-124_extended.tif' dtmfile = '/Users/raulvalenzuela/Dropbox/NOCAL_DEM/merged_dem_38-39_123-124_extended.tif' domain = [-123.4, -122.8, 38.8, 38.1, 8] elev = elevation(file_name=dtmfile, domain=domain) elev.get_elevation() elev_lims = [0,700] ls = LightSource(azdeg=15, altdeg=60) rgb = ls.shade(elev.dtm, cmap=getattr(plt.cm,cmap), vmin=elev_lims[0], vmax=elev_lims[1], blend_mode='soft', fraction=0.7) ax.imshow(rgb) " interpolate latlon to cartesian coords" nrows, ncols = elev.dtm.shape flat = interp1d(np.linspace(domain[3],domain[2],nrows), range(nrows)) flon = interp1d(np.linspace(domain[0], domain[1], ncols), range(ncols)) lat, lon = locations['FRS'] ax.scatter(flon(lon), flat(lat), color='r',s=50) lat, lon = locations['BBY'] ax.scatter(flon(lon), flat(lat), color='r',s=50) lat, lon = locations['CZD'] ax.scatter(flon(lon), flat(lat), color='r',s=50) 'Use a proxy artist for the colorbar' im = ax.imshow(elev.dtm, cmap=cmap, vmin=elev_lims[0], vmax=elev_lims[1], origin='lower', ) im.remove() add_colorbar(ax,im,label='Meters') ax.set_xticklabels('') ax.set_yticklabels('') plt.tight_layout() if saveto is not None: fname = 'shaded_terrain.png' plt.savefig(saveto + fname, dpi=300, format='png', papertype='letter', bbox_inches='tight')
# transform to metres nx = int((m.xmax - m.xmin) / 500.) + 1 ny = int((m.ymax - m.ymin) / 500.) + 1 topodat = m.transform_scalar(data, lons, lats, nx, ny) print('Getting colormap...') # get colormap cptfile = '//Users//trev//Documents//DATA//GMT//cpt//mby_topo-bath.cpt' #cptfile = '//Users//tallen//Documents//DATA//GMT//cpt//gray.cpt' cmap, zvals = cpt2colormap(cptfile, 256) cmap = remove_last_cmap_colour(cmap) # make shading print('Making map...') ls = LightSource(azdeg=180, altdeg=45) norm = mpl.colors.Normalize(vmin=-8000 / zscale, vmax=5000 / zscale) #myb rgb = ls.shade(topodat, cmap=cmap, norm=norm) im = m.imshow(rgb, alpha=0.6) ''' ########################################################################################## # add epicentres ########################################################################################## ncols = 18 # get year range minyear = 10*floor(cat.data['year'][0]/10.) maxyear = cat.data['year'][-1] yearrng = float(round(maxyear - minyear)) #cmap = plt.cm.get_cmap('Spectral', ncols)
y = (ny -np.arange(ny)) * dy X, Y = np.meshgrid(x, y) Z = data.reshape(ny, nx) import matplotlib.pyplot as plt import matplotlib fig = plt.figure(0) plt.clf() ax = fig. add_subplot(1,1,1) ax.set_aspect("equal") plt.contourf(X, Y, Z, 100, cmap = matplotlib.cm.terrain) cbar=plt.colorbar() cbar.set_label("Altitude, $z$ [m]") plt.contour(X, Y, Z, 20, colors= "k") plt.grid() plt.xlabel("Position, $x$ [m]") plt.ylabel("Position, $y$ [m]") from matplotlib.colors import LightSource ls= LightSource(aedeg=0, altdeg=65) rgb = ls.shade(Z, plt.cm.terrain) plt.figure(1) plt.imshow(rgb, extent=[0,x.max(),0,y.max()]) cbar = plt.colorbar(grad) cbar.set_label("Altitude, $z$ [m]") plt.xlabel("Position, $x$ [m]") plt.ylabel("Position, $y$ [m]") plt.show()
base_name = 'PNG/S03_interferences' # Le nom par défaut i = 0 # Initialisation du compteur for t in np.arange(tmin, tmax, dt): # On boucle sur le temps i += 1 # Incrémentation du compteur print(t) # Un peu de feedback Z1 = source(X, Y, t, -pos, 0) # La première source Z2 = source(X, Y, t, pos, 0, phi) # et la seconde # Ouverture de la figure et définition des sous-figures plt.figure(figsize=(8, 7.76)) ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=2, rowspan=2) plt.title('Interferences a deux sources, $t={}$'.format(round(t, 1))) plt.ylabel('$y$') if shading: ls = LightSource(azdeg=20, altdeg=65) # create light source object. rgb = ls.shade(Z1 + Z2, plt.cm.copper) # shade data, creating an rgb array. plt.imshow(rgb, extent=extent) else: plt.imshow(Z1 + Z2, interpolation='bilinear', extent=extent, cmap='jet', vmin=vmin, vmax=vmax) # Pour visualiser les deux plans de coupes plt.plot([-ext, ext], [ycut, ycut], '--k') plt.plot([xcut, xcut], [-ext, ext], '--k')
def _shade_colors_lightsource(self, data, cmap, lightsource): if lightsource is None: lightsource = LightSource(azdeg=135, altdeg=55) return lightsource.shade(data, cmap)
import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import LightSource from sng_image import IMAGE import matplotlib.mlab as mlab import matplotlib as mpl #DEM data test = IMAGE() data = test.read('fdem.tif') Z = data[0] Z[Z<0] = Z[Z>0].min() #Shade from the northwest, with the sun 45 degrees from horizontal ls = LightSource(azdeg=315, altdeg=45) cmap = plt.cm.gist_earth rgb = ls.shade(Z, cmap) plt.figure(figsize=(10,4)) plt.subplot(1,2,1) plt.title('dem') #method 1 - default # plt.imshow(Z, cmap=plt.cm.terrain ) #method 2 r,c = Z.shape x,y,dx,dy = data[1][0],data[1][3],data[1][1],data[1][5] xmin,xmax,ymin,ymax = x,x+c*dx,y+r*dy,y extent=[xmin, xmax,ymin, ymax] levels = np.arange(0, int(Z.max()), 200) # Boost the upper limit to avoid truncation errors. cmap = plt.cm.get_cmap(name='jet') #terrain,gist_earth,ocean,brg,hsv,Dark2,hot,gray plt.imshow(Z, cmap = cmap, interpolation='none', aspect='equal', \ origin='upper', extent=extent, vmax=Z.max(), vmin=Z.min()) x=np.arange(xmin,xmax,(xmax-xmin)/c) y=np.arange(ymax, ymin, (ymin- ymax)/r)
def remove_value(x, y, val1, val2, par, cond): #Remove from vector val1 and its coordinate z,y entries that are in the val1 array according to par in the val2 array if cond == 'gt': x = x[val2 > par] y = y[val2 > par] val1 = val1[val2 > par] else: x = x[val2 < par] y = y[val2 < par] val1 = val1[val2 < par] return x, y, val1 verticalEx = 0.1 ls = LightSource(azdeg=135, altdeg=30) path_data = '../data/sar/' lat_minimum = 19.31 lat_maximum = 19.48 lon_minimum = -155.40 lon_maximum = -155.15 lat_minimum_DEM = 19.31 lat_maximum_DEM = 19.48 lon_minimum_DEM = -155.40 lon_maximum_DEM = -155.15 coherence_thresh = 0.5
def draw_loss(model, X, epsilon, bn, name, dsbn=True, save=False, plot=False): Xi, Yi = np.meshgrid(np.linspace(-epsilon, epsilon, 14), np.linspace(-epsilon, epsilon, 14)) def grad_at_delta(delta): delta.requires_grad_(True) if dsbn: nn.BCELoss()(torch.sigmoid(model(X + delta, bn)), y).backward() else: nn.BCELoss()(torch.sigmoid(model(X + delta)), y).backward() return delta.grad.detach().sign().view(-1).cpu().numpy() dir1 = grad_at_delta(torch.zeros_like(X, requires_grad=True)) delta2 = torch.zeros_like(X, requires_grad=True) delta2.data = torch.tensor(dir1).view_as(X).cuda() dir2 = grad_at_delta(delta2) np.random.seed(0) dir2 = np.sign(np.random.randn(dir1.shape[0])) all_deltas = torch.tensor( (np.array([Xi.flatten(), Yi.flatten()]).T @ np.array( [dir2, dir1])).astype(np.float32)).cuda() all_deltas = all_deltas.view(-1, 3, 256, 256) Zi = torch.zeros(14 * 14) for n, delta in enumerate(all_deltas): if dsbn: yp = torch.sigmoid(model(delta + X, bn)) else: yp = torch.sigmoid(model(delta + X)) zi = nn.BCELoss(reduction="mean")(yp, y) Zi[n] = zi Zi = Zi.reshape(*Xi.shape).detach().cpu().numpy() #Zi = (Zi-Zi.min())/(Zi.max() - Zi.min()) if plot: fig = plt.figure(figsize=(10, 10)) ax = fig.gca(projection='3d') ls = LightSource(azdeg=0, altdeg=200) rgb = ls.shade(Zi, plt.cm.coolwarm) ax.set_zlim(0, 1.0) surf = ax.plot_surface(Xi, Yi, Zi, rstride=1, cstride=1, lw=0.5, antialiased=True, facecolors=rgb, alpha=0.7) surf = ax.contourf(Xi, Yi, Zi, zdir='z', offset=0, cmap=plt.cm.coolwarm) ax.set_xlabel(r'$\epsilon_{Rad.}$', fontsize=20) ax.set_ylabel(r'$\epsilon_{\nabla_x \mathcal{L}}$', fontsize=20) surf.set_clim(0.2, 0.8) # plt.show() if save: plt.savefig(name, format='png', dpi=500, bbox_inches='tight', pad_inches=0) plt.close() return Zi
'central_latitude': 0.0, } ax = plt.axes(projection=ccrs.Orthographic(**proj)) img_extent = (-180., 179.91667, -80., 90.) csfont = {'fontname': 'Ubuntu', 'color' : "white", 'size': 20} f.set_facecolor("black") f.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9, wspace=None, hspace=None) ls = LightSource(azdeg=315, altdeg=30) # Load in the first file to set up the figure with Dataset(sst_fh, mode='r') as nc: sst = np.flipud(nc.variables[sst_variable_name][0, 0, :, :]) sst = np.ma.masked_values(sst, 0) with Dataset(ice_fh, mode='r') as nc: ice = np.flipud(nc.variables[ice_variable_name][0, :, :]) ice = np.ma.masked_values(ice, 0) # Apply continents as a mask continent_mask = np.ma.getmask(sst).astype(int)
# nas interprets grids differently if cwd.startswith('/nas'): mmidat = m.transform_scalar(resampled.T, lons, lats, nx, ny) else: mmidat = m.transform_scalar(resampled, lons, lats, nx, ny) print 'Getting colormap...' # get colormap cptfile = '/nas/active/ops/community_safety/ehp/georisk_earthquake/hazard/DATA/cpt/mi_pop.cpt' cmap, zvals = cpt2colormap(cptfile, 256) #cmap=plt.get_cmap('Spectral',256) # make shading print 'Making map...' ls = LightSource(azdeg=180, altdeg=0) norm = mpl.colors.Normalize(vmin=0, vmax=11) #myb rgb = ls.shade_rgb(cmap(norm(mmidat)), topodat, blend_mode='hsv', vert_exag=1) im = m.imshow(rgb) ########################################################################################## # get land & lake polygons for masking ########################################################################################## polys = get_map_polygons(m) #mask_outside_polygon(polys[1][::-1], ax=None) mask_outside_polygons(polys, 'lightskyblue', plt)
def draw(self, filename): #DEM data rst = self.raster.read(filename) data = rst["data"] Z = data Z[Z < 0] = Z[Z > 0].min() #Shade from the northwest, with the sun 45 degrees from horizontal ls = LightSource(azdeg=315, altdeg=45) cmap = plt.cm.gist_earth rgb = ls.shade(Z, cmap) #Display plt.figure(figsize=(10, 4)) plt.subplot(1, 2, 1) plt.title('dem') #method 1 - default # plt.imshow(Z, cmap=plt.cm.terrain ) #method 2 r, c = Z.shape x, y, dx, dy = data[1][0], data[1][3], data[1][1], data[1][5] xmin, xmax, ymin, ymax = x, x + c * dx, y + r * dy, y extent = [xmin, xmax, ymin, ymax] levels = np.arange(0, int( Z.max()), 200) # Boost the upper limit to avoid truncation errors. cmap = plt.cm.get_cmap( name='jet') #terrain,gist_earth,ocean,brg,hsv,Dark2,hot,gray plt.imshow(Z, cmap = cmap, interpolation='none', aspect='equal', \ origin='upper', extent=extent, vmax=Z.max(), vmin=Z.min()) x = np.arange(xmin, xmax, (xmax - xmin) / c) y = np.arange(ymax, ymin, (ymin - ymax) / r) X, Y = np.meshgrid(x, y) # CS = plt.contour(X, Y, Z) CS = plt.contour(Z, levels, hold='on', colors='k', origin='upper', extent=extent, aspect='equal') # CS = plt.contour(Z, levels, hold='on', colors='k', origin='image', extent=extent) plt.clabel(CS, inline=1, fmt='%d', fontsize=10) plt.plot([xmin, xmax], [ymin, ymax], 'r--', lw=2) plt.gca().set_aspect(1.0) #plt.axes().set_aspect(1.0) plt.xlim(xmin, xmax) #method 3 # mpl.rcParams['image.cmap'] = 'gist_rainbow' # plt.set_cmap('gist_rainbow') # im=plt.imshow(Z) # plt.colorbar(im, orientation='horizontal') # plt.subplot(1, 2, 2) ax1 = plt.gca() ax1.set_title('hillshade') ax1.imshow(rgb) # fig = plt.gcf() fig.savefig('contour.png', format='png') plt.savefig('contour_01.jpg') plt.show()
def gen_fig_map(nivel_ref, lat_vol, lon_vol, latdelta, londelta, zona, cod, gs, factorlatlon, km, test_deg, op, fechas): ##CREACION DE MAPA ax2 = plt.subplot(gs[1]) url = "C:/nc/" + str(zona) + "/" + cod + ".nc" etopodata = Dataset(url) try: topoin = etopodata.variables['z'][:] lons = etopodata.variables['x'][:] lats = etopodata.variables['y'][:] except: topoin = etopodata.variables['z_range'][:] lons = etopodata.variables['x_range'][:] lats = etopodata.variables['y_range'][:] m = Basemap(projection='merc', llcrnrlat=lat_vol - latdelta, urcrnrlat=lat_vol + latdelta, llcrnrlon=lon_vol - londelta, urcrnrlon=lon_vol + londelta, lat_ts=(max(lats) + min(lats)) / 2, resolution='i') #LUZ ls = LightSource(azdeg=180, altdeg=60) # transform to nx x ny regularly spaced 5km native projection grid nx = int((m.xmax - m.xmin) / 50.) + 1 ny = int((m.ymax - m.ymin) / 50.) + 1 topodat, x, y = m.transform_scalar(topoin, lons, lats, nx, ny, returnxy=True) cmap = plt.get_cmap('gist_earth') def truncate_colormap(cmap, minval=0.0, maxval=1.0, n=100): new_cmap = colors.LinearSegmentedColormap.from_list( 'trunc({n},{a:.2f},{b:.2f})'.format(n=cmap.name, a=minval, b=maxval), cmap(np.linspace(minval, maxval, n))) return new_cmap new_cmap = truncate_colormap(cmap, 0.1, 0.7) # plot image over map with imshow. #im = m.imshow(topodat,cmap='gist_earth') rgb = ls.shade(topodat, new_cmap) #PLOTEO DE MAPA im = m.imshow(rgb, alpha=0.6) plt.gca().add_patch( patches.Rectangle((0, 0), km * 1250, km * 370, facecolor="#ffffff")) m.drawmapscale(lon_vol - (test_deg * 0.35), lat_vol - (latdelta * 0.875), lon_vol, lat_vol, km, barstyle='fancy', format='%.1f') if op == 'reav': () else: plt.text(0.02, 0.95, str(fechas[0]) + " - " + str(fechas[1]), fontsize=8, color='k', ha='left', bbox=dict(facecolor='111111', alpha=0.85, pad=2), transform=plt.gca().transAxes) return gs, m
import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import LightSource # example showing how to make shaded relief plots # like mathematica # (http://reference.wolfram.com/mathematica/ref/ReliefPlot.html ) # or Generic Mapping Tools # (http://gmt.soest.hawaii.edu/gmt/doc/gmt/html/GMT_Docs/node145.html) # test data X,Y=np.mgrid[-5:5:0.05,-5:5:0.05] Z=np.sqrt(X**2+Y**2)+np.sin(X**2+Y**2) # creat light source object. ls = LightSource(azdeg=0,altdeg=65) # shade data, creating an rgb array. rgb = ls.shade(Z,plt.cm.copper) # plot un-shaded and shaded images. plt.figure(figsize=(12,5)) plt.subplot(121) plt.imshow(Z,cmap=plt.cm.copper) plt.title('imshow') plt.xticks([]); plt.yticks([]) plt.subplot(122) plt.imshow(rgb) plt.title('imshow with shading') plt.xticks([]); plt.yticks([]) plt.show()
""" Shaded map of Mount Saint Helens By Richard Essery """ import numpy as np from matplotlib import pylab as plt from matplotlib.colors import LightSource z = np.loadtxt('MtStHelens.txt') ls = LightSource(azdeg=-45, altdeg=45) shade = ls.shade(z, cmap=plt.cm.gray) plt.imshow(shade, origin='lower') plt.xticks([]) plt.yticks([]) plt.show()
import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import LightSource # example showing how to make shaded relief plots # like Mathematica # (http://reference.wolfram.com/mathematica/ref/ReliefPlot.html) # or Generic Mapping Tools # (http://gmt.soest.hawaii.edu/gmt/doc/gmt/html/GMT_Docs/node145.html) # test data X, Y = np.mgrid[-5:5:0.05, -5:5:0.05] Z = np.sqrt(X**2 + Y**2) + np.sin(X**2 + Y**2) # create light source object. ls = LightSource(azdeg=0, altdeg=65) # shade data, creating an rgb array. rgb = ls.shade(Z, plt.cm.copper) # plot un-shaded and shaded images. plt.figure(figsize=(12, 5)) plt.subplot(121) plt.imshow(Z, cmap=plt.cm.copper) plt.title('imshow') plt.xticks([]) plt.yticks([]) plt.subplot(122) plt.imshow(rgb) plt.title('imshow with shading') plt.xticks([]) plt.yticks([]) plt.show()
# Load and format data with cbook.get_sample_data('jacksboro_fault_dem.npz') as file, \ np.load(file) as dem: z = dem['elevation'] nrows, ncols = z.shape x = np.linspace(dem['xmin'], dem['xmax'], ncols) y = np.linspace(dem['ymin'], dem['ymax'], nrows) x, y = np.meshgrid(x, y) region = np.s_[5:50, 5:50] x, y, z = x[region], y[region], z[region] # Set up plot fig, ax = plt.subplots(subplot_kw=dict(projection='3d')) ls = LightSource(270, 45) # To use a custom hillshading mode, override the built-in shading and pass # in the rgb colors of the shaded surface calculated from "shade". rgb = ls.shade(z, cmap=cm.gist_earth, vert_exag=0.1, blend_mode='soft') surf = ax.plot_surface(x, y, z, rstride=1, cstride=1, facecolors=rgb, linewidth=0, antialiased=False, shade=False) plt.show()
def modelMap(grids, shakefile=None, suptitle=None, inventory_shapefile=None, plotorder=None, maskthreshes=None, colormaps=None, boundaries=None, zthresh=0, scaletype='continuous', lims=None, logscale=False, ALPHA=0.7, maproads=True, mapcities=True, isScenario=False, roadfolder=None, topofile=None, cityfile=None, oceanfile=None, roadcolor='#6E6E6E', watercolor='#B8EEFF', countrycolor='#177F10', outputdir=None, savepdf=True, savepng=True, showplots=False, roadref='unknown', cityref='unknown', oceanref='unknown', printparam=False, ds=True, dstype='mean', upsample=False): """ This function creates maps of mapio grid layers (e.g. liquefaction or landslide models with their input layers) All grids must use the same bounds TO DO change so that all input layers do not have to have the same bounds, test plotting multiple probability layers, and add option so that if PDF and PNG aren't output, opens plot on screen using plt.show() :param grids: Dictionary of N layers and metadata formatted like: maplayers['layer name']={ 'grid': mapio grid2D object, 'label': 'label for colorbar and top line of subtitle', 'type': 'output or input to model', 'description': 'detailed description of layer for subtitle'}. Layer names must be unique. :type name: Dictionary or Ordered dictionary - import collections; grids = collections.OrderedDict() :param shakefile: optional ShakeMap file (url or full file path) to extract information for labels and folder names :type shakefile: Shakemap Event Dictionary :param suptitle: This will be displayed at the top of the plots and in the figure names :type suptitle: string :param plotorder: List of keys describing the order to plot the grids, if None and grids is an ordered dictionary, it will use the order of the dictionary, otherwise it will choose order which may be somewhat random but it will always put a probability grid first :type plotorder: list :param maskthreshes: N x 1 array or list of lower thresholds for masking corresponding to order in plotorder or order of OrderedDict if plotorder is None. If grids is not an ordered dict and plotorder is not specified, this will not work right. If None (default), nothing will be masked :param colormaps: List of strings of matplotlib colormaps (e.g. cm.autumn_r) corresponding to plotorder or order of dictionary if plotorder is None. The list can contain both strings and None e.g. colormaps = ['cm.autumn', None, None, 'cm.jet'] and None's will default to default colormap :param boundaries: None to show entire study area, 'zoom' to zoom in on the area of action (only works if there is a probability layer) using zthresh as a threshold, or a dictionary defining lats and lons in the form of boundaries.xmin = minlon, boundaries.xmax = maxlon, boundaries.ymin = min lat, boundaries.ymax = max lat :param zthresh: threshold for computing zooming bounds, only used if boundaries = 'zoom' :type zthresh: float :param scaletype: Type of scale for plotting, 'continuous' or 'binned' - will be reflected in colorbar :type scaletype: string :param lims: None or Nx1 list of tuples or numpy arrays corresponding to plotorder defining the limits for saturating the colorbar (vmin, vmax) if scaletype is continuous or the bins to use (clev) if scaletype if binned. The list can contain tuples, arrays, and Nones, e.g. lims = [(0., 10.), None, (0.1, 1.5), np.linspace(0., 1.5, 15)]. When None is specified, the program will estimate the limits, when an array is specified but the scale type is continuous, vmin will be set to min(array) and vmax will be set to max(array) :param lims: None or Nx1 list of Trues and Falses corresponding to plotorder defining whether to use a linear or log scale (log10) for plotting the layer. This will be reflected in the labels :param ALPHA: Transparency for mapping, if there is a hillshade that will plot below each layer, it is recommended to set this to at least 0.7 :type ALPHA: float :param maproads: Whether to show roads or not, default True, but requires that roadfile is specified and valid to work :type maproads: boolean :param mapcities: Whether to show cities or not, default True, but requires that cityfile is specified and valid to work :type mapcities: boolean :param isScenario: Whether this is a scenario (True) or a real event (False) (default False) :type isScenario: boolean :param roadfolder: Full file path to folder containing road shapefiles :type roadfolder: string :param topofile: Full file path to topography grid (GDAL compatible) - this is only needed to make a hillshade if a premade hillshade is not specified :type topofile: string :param cityfile: Full file path to Pager file containing city & population information :type cityfile: string :param roadcolor: Color to use for roads, if plotted, default #6E6E6E :type roadcolor: Hex color or other matplotlib compatible way of defining color :param watercolor: Color to use for oceans, lakes, and rivers, default #B8EEFF :type watercolor: Hex color or other matplotlib compatible way of defining color :param countrycolor: Color for country borders, default #177F10 :type countrycolor: Hex color or other matplotlib compatible way of defining color :param outputdir: File path for outputting figures, if edict is defined, a subfolder based on the event id will be created in this folder. If None, will use current directory :param savepdf: True to save pdf figure, False to not :param savepng: True to save png figure, False to not :param ds: True to allow downsampling for display (necessary when arrays are quite large, False to not allow) :param dstype: What function to use in downsampling, options are 'min', 'max', 'median', or 'mean' :param upsample: True to upsample the layer to the DEM resolution for better looking hillshades :returns: * PDF and/or PNG of map * Downsampled and trimmed version of input grids. If no modification was needed for plotting, this will be identical to grids but without the metadata """ if suptitle is None: suptitle = ' ' plt.ioff() defaultcolormap = cm.jet if shakefile is not None: edict = ShakeGrid.load(shakefile, adjust='res').getEventDict() temp = ShakeGrid.load(shakefile, adjust='res').getShakeDict() edict['eventid'] = temp['shakemap_id'] edict['version'] = temp['shakemap_version'] else: edict = None # Get output file location if outputdir is None: print('No output location given, using current directory for outputs\n') outputdir = os.getcwd() if edict is not None: outfolder = os.path.join(outputdir, edict['event_id']) else: outfolder = outputdir if not os.path.isdir(outfolder): os.makedirs(outfolder) # Get plotting order, if not specified if plotorder is None: plotorder = list(grids.keys()) # Get boundaries to use for all plots cut = True if boundaries is None: cut = False keytemp = list(grids.keys()) boundaries = grids[keytemp[0]]['grid'].getGeoDict() elif boundaries == 'zoom': # Find probability layer (will just take the maximum bounds if there is # more than one) keytemp = list(grids.keys()) key1 = [key for key in keytemp if 'model' in key.lower()] if len(key1) == 0: print('Could not find model layer to use for zoom, using default boundaries') keytemp = list(grids.keys()) boundaries = grids[keytemp[0]]['grid'].getGeoDict() else: lonmax = -1.e10 lonmin = 1.e10 latmax = -1.e10 latmin = 1.e10 for key in key1: # get lat lons of areas affected and add, if no areas affected, # switch to shakemap boundaries temp = grids[key]['grid'] xmin, xmax, ymin, ymax = temp.getBounds() lons = np.linspace(xmin, xmax, temp.getGeoDict().nx) lats = np.linspace(ymax, ymin, temp.getGeoDict().ny) # backwards so it plots right row, col = np.where(temp.getData() > float(zthresh)) lonmin = lons[col].min() lonmax = lons[col].max() latmin = lats[row].min() latmax = lats[row].max() # llons, llats = np.meshgrid(lons, lats) # make meshgrid # llons1 = llons[temp.getData() > float(zthresh)] # llats1 = llats[temp.getData() > float(zthresh)] # if llons1.min() < lonmin: # lonmin = llons1.min() # if llons1.max() > lonmax: # lonmax = llons1.max() # if llats1.min() < latmin: # latmin = llats1.min() # if llats1.max() > latmax: # latmax = llats1.max() boundaries1 = {'dx': 100, 'dy': 100., 'nx': 100., 'ny': 100} # dummy fillers, only really care about bounds if xmin < lonmin-0.15*(lonmax-lonmin): boundaries1['xmin'] = lonmin-0.1*(lonmax-lonmin) else: boundaries1['xmin'] = xmin if xmax > lonmax+0.15*(lonmax-lonmin): boundaries1['xmax'] = lonmax+0.1*(lonmax-lonmin) else: boundaries1['xmax'] = xmax if ymin < latmin-0.15*(latmax-latmin): boundaries1['ymin'] = latmin-0.1*(latmax-latmin) else: boundaries1['ymin'] = ymin if ymax > latmax+0.15*(latmax-latmin): boundaries1['ymax'] = latmax+0.1*(latmax-latmin) else: boundaries1['ymax'] = ymax boundaries = GeoDict(boundaries1, adjust='res') else: # SEE IF BOUNDARIES ARE SAME AS BOUNDARIES OF LAYERS keytemp = list(grids.keys()) tempgdict = grids[keytemp[0]]['grid'].getGeoDict() if np.abs(tempgdict.xmin-boundaries['xmin']) < 0.05 and \ np.abs(tempgdict.ymin-boundaries['ymin']) < 0.05 and \ np.abs(tempgdict.xmax-boundaries['xmax']) < 0.05 and \ np.abs(tempgdict.ymax - boundaries['ymax']) < 0.05: print('Input boundaries are almost the same as specified boundaries, no cutting needed') boundaries = tempgdict cut = False else: try: if boundaries['xmin'] > boundaries['xmax'] or \ boundaries['ymin'] > boundaries['ymax']: print('Input boundaries are not usable, using default boundaries') keytemp = list(grids.keys()) boundaries = grids[keytemp[0]]['grid'].getGeoDict() cut = False else: # Build dummy GeoDict boundaries = GeoDict({'xmin': boundaries['xmin'], 'xmax': boundaries['xmax'], 'ymin': boundaries['ymin'], 'ymax': boundaries['ymax'], 'dx': 100., 'dy': 100., 'ny': 100., 'nx': 100.}, adjust='res') except: print('Input boundaries are not usable, using default boundaries') keytemp = list(grids.keys()) boundaries = grids[keytemp[0]]['grid'].getGeoDict() cut = False # Pull out bounds for various uses bxmin, bxmax, bymin, bymax = boundaries.xmin, boundaries.xmax, boundaries.ymin, boundaries.ymax # Determine if need a single panel or multi-panel plot and if multi-panel, # how many and how it will be arranged fig = plt.figure() numpanels = len(grids) if numpanels == 1: rowpan = 1 colpan = 1 # create the figure and axes instances. fig.set_figwidth(5) elif numpanels == 2 or numpanels == 4: rowpan = np.ceil(numpanels/2.) colpan = 2 fig.set_figwidth(13) else: rowpan = np.ceil(numpanels/3.) colpan = 3 fig.set_figwidth(15) if rowpan == 1: fig.set_figheight(rowpan*6.0) else: fig.set_figheight(rowpan*5.3) # Need to update naming to reflect the shakemap version once can get # getHeaderData to work, add edict['version'] back into title, maybe # shakemap id also? fontsizemain = 14. fontsizesub = 12. fontsizesmallest = 10. if rowpan == 1.: fontsizemain = 12. fontsizesub = 10. fontsizesmallest = 8. if edict is not None: if isScenario: title = edict['event_description'] else: timestr = edict['event_timestamp'].strftime('%b %d %Y') title = 'M%.1f %s v%i - %s' % (edict['magnitude'], timestr, edict['version'], edict['event_description']) plt.suptitle(title+'\n'+suptitle, fontsize=fontsizemain) else: plt.suptitle(suptitle, fontsize=fontsizemain) clear_color = [0, 0, 0, 0.0] # Cut all of them and release extra memory xbuff = (bxmax-bxmin)/10. ybuff = (bymax-bymin)/10. cutxmin = bxmin-xbuff cutymin = bymin-ybuff cutxmax = bxmax+xbuff cutymax = bymax+ybuff if cut is True: newgrids = collections.OrderedDict() for k, layer in enumerate(plotorder): templayer = grids[layer]['grid'] try: newgrids[layer] = {'grid': templayer.cut(cutxmin, cutxmax, cutymin, cutymax, align=True)} except Exception as e: print(('Cutting failed, %s, continuing with full layers' % e)) newgrids = grids continue del templayer gc.collect() else: newgrids = grids tempgdict = newgrids[list(grids.keys())[0]]['grid'].getGeoDict() # Upsample layers to same as topofile if desired for better looking hillshades if upsample is True and topofile is not None: try: topodict = GDALGrid.getFileGeoDict(topofile) if topodict.dx >= tempgdict.dx or topodict.dy >= tempgdict.dy: print('Upsampling not possible, resolution of results already smaller than DEM') pass else: tempgdict1 = GeoDict({'xmin': tempgdict.xmin-xbuff, 'ymin': tempgdict.ymin-ybuff, 'xmax': tempgdict.xmax+xbuff, 'ymax': tempgdict.ymax+ybuff, 'dx': topodict.dx, 'dy': topodict.dy, 'nx': topodict.nx, 'ny': topodict.ny}, adjust='res') tempgdict2 = tempgdict1.getBoundsWithin(tempgdict) for k, layer in enumerate(plotorder): newgrids[layer]['grid'] = newgrids[layer]['grid'].subdivide(tempgdict2) except: print('Upsampling failed, continuing') # Downsample all of them for plotting, if needed, and replace them in # grids (to save memory) tempgrid = newgrids[list(grids.keys())[0]]['grid'] xsize = tempgrid.getGeoDict().nx ysize = tempgrid.getGeoDict().ny inchesx, inchesy = fig.get_size_inches() divx = int(np.round(xsize/(500.*inchesx))) divy = int(np.round(ysize/(500.*inchesy))) xmin, xmax, ymin, ymax = tempgrid.getBounds() gdict = tempgrid.getGeoDict() # Will be replaced if downsampled del tempgrid gc.collect() if divx <= 1: divx = 1 if divy <= 1: divy = 1 if (divx > 1. or divy > 1.) and ds: if dstype == 'max': func = np.nanmax elif dstype == 'min': func = np.nanmin elif dstype == 'med': func = np.nanmedian else: func = np.nanmean for k, layer in enumerate(plotorder): layergrid = newgrids[layer]['grid'] dat = block_reduce(layergrid.getData().copy(), block_size=(divy, divx), cval=float('nan'), func=func) if k == 0: lons = block_reduce(np.linspace(xmin, xmax, layergrid.getGeoDict().nx), block_size=(divx,), func=np.mean, cval=float('nan')) if math.isnan(lons[-1]): lons[-1] = lons[-2] + (lons[1]-lons[0]) lats = block_reduce(np.linspace(ymax, ymin, layergrid.getGeoDict().ny), block_size=(divy,), func=np.mean, cval=float('nan')) if math.isnan(lats[-1]): lats[-1] = lats[-2] + (lats[1]-lats[0]) gdict = GeoDict({'xmin': lons.min(), 'xmax': lons.max(), 'ymin': lats.min(), 'ymax': lats.max(), 'dx': np.abs(lons[1]-lons[0]), 'dy': np.abs(lats[1]-lats[0]), 'nx': len(lons), 'ny': len(lats)}, adjust='res') newgrids[layer]['grid'] = Grid2D(dat, gdict) del layergrid, dat else: lons = np.linspace(xmin, xmax, xsize) lats = np.linspace(ymax, ymin, ysize) # backwards so it plots right side up #make meshgrid llons1, llats1 = np.meshgrid(lons, lats) # See if there is an oceanfile for masking bbox = PolygonSH(((cutxmin, cutymin), (cutxmin, cutymax), (cutxmax, cutymax), (cutxmax, cutymin))) if oceanfile is not None: try: f = fiona.open(oceanfile) oc = next(f) f.close shapes = shape(oc['geometry']) # make boundaries into a shape ocean = shapes.intersection(bbox) except: print('Not able to read specified ocean file, will use default ocean masking') oceanfile = None if inventory_shapefile is not None: try: f = fiona.open(inventory_shapefile) invshp = list(f.items(bbox=(bxmin, bymin, bxmax, bymax))) f.close() inventory = [shape(inv[1]['geometry']) for inv in invshp] except: print('unable to read inventory shapefile specified, will not plot inventory') inventory_shapefile = None # # Find cities that will be plotted if mapcities is True and cityfile is not None: try: mycity = BasemapCities.loadFromGeoNames(cityfile=cityfile) bcities = mycity.limitByBounds((bxmin, bxmax, bymin, bymax)) #bcities = bcities.limitByPopulation(40000) bcities = bcities.limitByGrid(nx=4, ny=4, cities_per_grid=2) except: print('Could not read in cityfile, not plotting cities') mapcities = False cityfile = None # Load in topofile if topofile is not None: try: topomap = GDALGrid.load(topofile, resample=True, method='linear', samplegeodict=gdict) except: topomap = GMTGrid.load(topofile, resample=True, method='linear', samplegeodict=gdict) topodata = topomap.getData().copy() # mask oceans if don't have ocean shapefile if oceanfile is None: topodata = maskoceans(llons1, llats1, topodata, resolution='h', grid=1.25, inlands=True) else: print('no hillshade is possible\n') topomap = None topodata = None # Load in roads, if needed if maproads is True and roadfolder is not None: try: roadslist = [] for folder in os.listdir(roadfolder): road1 = os.path.join(roadfolder, folder) shpfiles = glob.glob(os.path.join(road1, '*.shp')) if len(shpfiles): shpfile = shpfiles[0] f = fiona.open(shpfile) shapes = list(f.items(bbox=(bxmin, bymin, bxmax, bymax))) for shapeid, shapedict in shapes: roadslist.append(shapedict) f.close() except: print('Not able to plot roads') roadslist = None val = 1 for k, layer in enumerate(plotorder): layergrid = newgrids[layer]['grid'] if 'label' in list(grids[layer].keys()): label1 = grids[layer]['label'] else: label1 = layer try: sref = grids[layer]['description']['name'] except: sref = None ax = fig.add_subplot(rowpan, colpan, val) val += 1 clat = bymin + (bymax-bymin)/2.0 clon = bxmin + (bxmax-bxmin)/2.0 # setup of basemap ('lcc' = lambert conformal conic). # use major and minor sphere radii from WGS84 ellipsoid. m = Basemap(llcrnrlon=bxmin, llcrnrlat=bymin, urcrnrlon=bxmax, urcrnrlat=bymax, rsphere=(6378137.00, 6356752.3142), resolution='l', area_thresh=1000., projection='lcc', lat_1=clat, lon_0=clon, ax=ax) x1, y1 = m(llons1, llats1) # get projection coordinates axsize = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted()) if k == 0: wid, ht = axsize.width, axsize.height if colormaps is not None and \ len(colormaps) == len(newgrids) and \ colormaps[k] is not None: palette = colormaps[k] else: # Find preferred default color map for each type of layer if 'prob' in layer.lower() or 'pga' in layer.lower() or \ 'pgv' in layer.lower() or 'cohesion' in layer.lower() or \ 'friction' in layer.lower() or 'fs' in layer.lower(): palette = cm.jet elif 'slope' in layer.lower(): palette = cm.gnuplot2 elif 'precip' in layer.lower(): palette = cm2.s3pcpn else: palette = defaultcolormap if topodata is not None: if k == 0: ptopo = m.transform_scalar( np.flipud(topodata), lons+0.5*gdict.dx, lats[::-1]-0.5*gdict.dy, np.round(300.*wid), np.round(300.*ht), returnxy=False, checkbounds=False, order=1, masked=False) #use lightsource class to make our shaded topography ls = LightSource(azdeg=135, altdeg=45) ls1 = LightSource(azdeg=120, altdeg=45) ls2 = LightSource(azdeg=225, altdeg=45) intensity1 = ls1.hillshade(ptopo, fraction=0.25, vert_exag=1.) intensity2 = ls2.hillshade(ptopo, fraction=0.25, vert_exag=1.) intensity = intensity1*0.5 + intensity2*0.5 #hillshm_im = m.transform_scalar(np.flipud(hillshm), lons, lats[::-1], np.round(300.*wid), np.round(300.*ht), returnxy=False, checkbounds=False, order=0, masked=False) #m.imshow(hillshm_im, cmap='Greys', vmin=0., vmax=3., zorder=1, interpolation='none') # vmax = 3 to soften colors to light gray #m.pcolormesh(x1, y1, hillshm, cmap='Greys', linewidth=0., rasterized=True, vmin=0., vmax=3., edgecolors='none', zorder=1); # plt.draw() # Get the data dat = layergrid.getData().copy() # mask out anything below any specified thresholds # Might need to move this up to before downsampling...might give illusion of no hazard in places where there is some that just got averaged out if maskthreshes is not None and len(maskthreshes) == len(newgrids): if maskthreshes[k] is not None: dat[dat <= maskthreshes[k]] = float('NaN') dat = np.ma.array(dat, mask=np.isnan(dat)) if logscale is not False and len(logscale) == len(newgrids): if logscale[k] is True: dat = np.log10(dat) label1 = r'$log_{10}$(' + label1 + ')' if scaletype.lower() == 'binned': # Find order of range to know how to scale order = np.round(np.log(np.nanmax(dat) - np.nanmin(dat))) if order < 1.: scal = 10**-order else: scal = 1. if lims is None or len(lims) != len(newgrids): clev = (np.linspace(np.floor(scal*np.nanmin(dat)), np.ceil(scal*np.nanmax(dat)), 10))/scal else: if lims[k] is None: clev = (np.linspace(np.floor(scal*np.nanmin(dat)), np.ceil(scal*np.nanmax(dat)), 10))/scal else: clev = lims[k] # Adjust to colorbar levels dat[dat < clev[0]] = clev[0] for j, level in enumerate(clev[:-1]): dat[(dat >= clev[j]) & (dat < clev[j+1])] = clev[j] # So colorbar saturates at top dat[dat > clev[-1]] = clev[-1] #panelhandle = m.contourf(x1, y1, datm, clev, cmap=palette, linewidth=0., alpha=ALPHA, rasterized=True) vmin = clev[0] vmax = clev[-1] else: if lims is not None and len(lims) == len(newgrids): if lims[k] is None: vmin = np.nanmin(dat) vmax = np.nanmax(dat) else: vmin = lims[k][0] vmax = lims[k][-1] else: vmin = np.nanmin(dat) vmax = np.nanmax(dat) # Mask out cells overlying oceans or block with a shapefile if available if oceanfile is None: dat = maskoceans(llons1, llats1, dat, resolution='h', grid=1.25, inlands=True) else: #patches = [] if type(ocean) is PolygonSH: ocean = [ocean] for oc in ocean: patch = getProjectedPatch(oc, m, edgecolor="#006280", facecolor=watercolor, lw=0.5, zorder=4.) #x, y = m(oc.exterior.xy[0], oc.exterior.xy[1]) #xy = zip(x, y) #patch = Polygon(xy, facecolor=watercolor, edgecolor="#006280", lw=0.5, zorder=4.) ##patches.append(Polygon(xy, facecolor=watercolor, edgecolor=watercolor, zorder=500.)) ax.add_patch(patch) ##ax.add_collection(PatchCollection(patches)) if inventory_shapefile is not None: for in1 in inventory: if 'point' in str(type(in1)): x, y = in1.xy x = x[0] y = y[0] m.scatter(x, y, c='m', s=50, latlon=True, marker='^', zorder=100001) else: x, y = m(in1.exterior.xy[0], in1.exterior.xy[1]) xy = list(zip(x, y)) patch = Polygon(xy, facecolor='none', edgecolor='k', lw=0.5, zorder=10.) #patches.append(Polygon(xy, facecolor=watercolor, edgecolor=watercolor, zorder=500.)) ax.add_patch(patch) palette.set_bad(clear_color, alpha=0.0) # Plot it up dat_im = m.transform_scalar( np.flipud(dat), lons+0.5*gdict.dx, lats[::-1]-0.5*gdict.dy, np.round(300.*wid), np.round(300.*ht), returnxy=False, checkbounds=False, order=0, masked=True) if topodata is not None: # Drape over hillshade #turn data into an RGBA image cmap = palette #adjust data so scaled between vmin and vmax and between 0 and 1 dat1 = dat_im.copy() dat1[dat1 < vmin] = vmin dat1[dat1 > vmax] = vmax dat1 = (dat1 - vmin)/(vmax-vmin) rgba_img = cmap(dat1) maskvals = np.dstack((dat1.mask, dat1.mask, dat1.mask)) rgb = np.squeeze(rgba_img[:, :, 0:3]) rgb[maskvals] = 1. draped_hsv = ls.blend_hsv(rgb, np.expand_dims(intensity, 2)) m.imshow(draped_hsv, zorder=3., interpolation='none') # This is just a dummy layer that will be deleted to make the # colorbar look right panelhandle = m.imshow(dat_im, cmap=palette, zorder=0., vmin=vmin, vmax=vmax) else: panelhandle = m.imshow(dat_im, cmap=palette, zorder=3., vmin=vmin, vmax=vmax, interpolation='none') #panelhandle = m.pcolormesh(x1, y1, dat, linewidth=0., cmap=palette, vmin=vmin, vmax=vmax, alpha=ALPHA, rasterized=True, zorder=2.); #panelhandle.set_edgecolors('face') # add colorbar cbfmt = '%1.1f' if vmax is not None and vmin is not None: if (vmax - vmin) < 1.: cbfmt = '%1.2f' elif vmax > 5.: # (vmax - vmin) > len(clev): cbfmt = '%1.0f' #norm = mpl.colors.Normalize(vmin=vmin, vmax=vmax) if scaletype.lower() == 'binned': cbar = fig.colorbar(panelhandle, spacing='proportional', ticks=clev, boundaries=clev, fraction=0.036, pad=0.04, format=cbfmt, extend='both') #cbar1 = ColorbarBase(cbar.ax, cmap=palette, norm=norm, spacing='proportional', ticks=clev, boundaries=clev, fraction=0.036, pad=0.04, format=cbfmt, extend='both', extendfrac='auto') else: cbar = fig.colorbar(panelhandle, fraction=0.036, pad=0.04, extend='both', format=cbfmt) #cbar1 = ColorbarBase(cbar.ax, cmap=palette, norm=norm, fraction=0.036, pad=0.04, extend='both', extendfrac='auto', format=cbfmt) if topodata is not None: panelhandle.remove() cbar.set_label(label1, fontsize=10) cbar.ax.tick_params(labelsize=8) parallels = m.drawparallels(getMapLines(bymin, bymax, 3), labels=[1, 0, 0, 0], linewidth=0.5, labelstyle='+/-', fontsize=9, xoffset=-0.8, color='gray', zorder=100.) m.drawmeridians(getMapLines(bxmin, bxmax, 3), labels=[0, 0, 0, 1], linewidth=0.5, labelstyle='+/-', fontsize=9, color='gray', zorder=100.) for par in parallels: try: parallels[par][1][0].set_rotation(90) except: pass #draw roads on the map, if they were provided to us if maproads is True and roadslist is not None: try: for road in roadslist: try: xy = list(road['geometry']['coordinates']) roadx, roady = list(zip(*xy)) mapx, mapy = m(roadx, roady) m.plot(mapx, mapy, roadcolor, lw=0.5, zorder=9) except: continue except Exception as e: print(('Failed to plot roads, %s' % e)) #add city names to map if mapcities is True and cityfile is not None: try: fontname = 'Arial' fontsize = 8 if k == 0: # Only need to choose cities first time and then apply to rest fcities = bcities.limitByMapCollision( m, fontname=fontname, fontsize=fontsize) ctlats, ctlons, names = fcities.getCities() cxis, cyis = m(ctlons, ctlats) for ctlat, ctlon, cxi, cyi, name in zip(ctlats, ctlons, cxis, cyis, names): m.scatter(ctlon, ctlat, c='k', latlon=True, marker='.', zorder=100000) ax.text(cxi, cyi, name, fontname=fontname, fontsize=fontsize, zorder=100000) except Exception as e: print('Failed to plot cities, %s' % e) #draw star at epicenter plt.sca(ax) if edict is not None: elat, elon = edict['lat'], edict['lon'] ex, ey = m(elon, elat) plt.plot(ex, ey, '*', markeredgecolor='k', mfc='None', mew=1.0, ms=15, zorder=10000.) m.drawmapboundary(fill_color=watercolor) m.fillcontinents(color=clear_color, lake_color=watercolor) m.drawrivers(color=watercolor) ##m.drawcoastlines() #draw country boundaries m.drawcountries(color=countrycolor, linewidth=1.0) #add map scale m.drawmapscale((bxmax+bxmin)/2., (bymin+(bymax-bymin)/9.), clon, clat, np.round((((bxmax-bxmin)*111)/5)/10.)*10, barstyle='fancy', zorder=10) # Add border autoAxis = ax.axis() rec = Rectangle((autoAxis[0]-0.7, autoAxis[2]-0.2), (autoAxis[1]-autoAxis[0])+1, (autoAxis[3]-autoAxis[2])+0.4, fill=False, lw=1, zorder=1e8) rec = ax.add_patch(rec) rec.set_clip_on(False) plt.draw() if sref is not None: label2 = '%s\nsource: %s' % (label1, sref) # '%s\n' % label1 + r'{\fontsize{10pt}{3em}\selectfont{}%s}' % sref # else: label2 = label1 plt.title(label2, axes=ax, fontsize=fontsizesub) #draw scenario watermark, if scenario if isScenario: plt.sca(ax) cx, cy = m(clon, clat) plt.text(cx, cy, 'SCENARIO', rotation=45, alpha=0.10, size=72, ha='center', va='center', color='red') #if ds: # Could add this to print "downsampled" on map # plt.text() if k == 1 and rowpan == 1: # adjust single level plot axsize = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted()) ht2 = axsize.height fig.set_figheight(ht2*1.6) else: plt.tight_layout() # Make room for suptitle - tight layout doesn't account for it plt.subplots_adjust(top=0.92) if printparam is True: try: fig = plt.gcf() dictionary = grids['model']['description']['parameters'] paramstring = 'Model parameters: ' halfway = np.ceil(len(dictionary)/2.) for i, key in enumerate(dictionary): if i == halfway and colpan == 1: paramstring += '\n' paramstring += ('%s = %s; ' % (key, dictionary[key])) print(paramstring) fig.text(0.01, 0.015, paramstring, fontsize=fontsizesmallest) plt.draw() except: print('Could not display model parameters') if edict is not None: eventid = edict['eventid'] else: eventid = '' time1 = datetime.datetime.utcnow().strftime('%d%b%Y_%H%M') outfile = os.path.join(outfolder, '%s_%s_%s.pdf' % (eventid, suptitle, time1)) pngfile = os.path.join(outfolder, '%s_%s_%s.png' % (eventid, suptitle, time1)) if savepdf is True: print('Saving map output to %s' % outfile) plt.savefig(outfile, dpi=300) if savepng is True: print('Saving map output to %s' % pngfile) plt.savefig(pngfile) if showplots is True: plt.show() else: plt.close(fig) return newgrids
# rgbRawScl00_g = np.zeros((SzY, SzX, 1)) # rgbRawScl00_b = np.zeros((SzY, SzX, 1)) # # # rgbRawScl00_r[:, :, 0] = rgbRawScl00 # rgbRawScl00_g[:, :, 0] = rgbRawScl00 # rgbRawScl00_b[:, :, 0] = rgbRawScl00 # # # rgbRawScl00_img = np.dstack((rgbRawScl00_r, rgbRawScl00_g, rgbRawScl00_b)) # print('size of rgbRawScl00_img = '+str(rgbRawScl00_img.shape)) # create light source object. ls00 = LightSource(azdeg=0, altdeg=66) ls01 = LightSource(azdeg=0, altdeg=66) ls02 = LightSource(azdeg=0, altdeg=66) ls03 = LightSource(azdeg=0, altdeg=66) ls04 = LightSource(azdeg=0, altdeg=66) ls05 = LightSource(azdeg=0, altdeg=13) ls06 = LightSource(azdeg=0, altdeg=26) ls07 = LightSource(azdeg=0, altdeg=108) ls08 = LightSource(azdeg=0, altdeg=156) #rgb = ls.shade(Z, plt.cm.gnuplot_r) shade00 = ls00.shade(Z00, plt.cm.gist_gray) shade01 = ls01.shade(Z01, plt.cm.gist_gray)
def on_draw(self): logger.debug("redraw") cur_sed = self.seds_list.currentText() cur_freq_khz = self.freq_slider.value() plot_spectral = self.spectral_cb.isChecked() self.jm2.use_test_sed_params(self.seds[cur_sed]) self.jm2.mdl_params.f = cur_freq_khz * 1000 self.jm2.run() self.freq_label.setText("Frequency [%.1f kHz]" % (self.jm2.mdl_params.f / 1000)) self.up_ax.clear() freqs_khz = [ 1.0, 3.0, 5.0, 10.0, 15.0, 20.0, 30.0, 50.0, 75.0, 100.0, 130.0, 160.0, 200.0, 250.0, 300.0, 350.0, 400.0, 450.0, 500.0 ] thetas = self.jm2.out.theta_i x, y = np.meshgrid(thetas, freqs_khz) if (self._last_sed != cur_sed) and (plot_spectral): logger.debug("recalculating thetas, freqs, and ss ...") self._ss = np.full((len(freqs_khz), thetas.size), np.nan) for i, f_khz in enumerate(freqs_khz): jm2 = Model() jm2.use_test_sed_params(self.seds[cur_sed]) jm2.use_default_mdl_params() jm2.mdl_params.f = f_khz * 1000 jm2.run() for j, theta in enumerate(range(jm2.out.theta_i.size)): self._ss[i, j] = jm2.out.ss_tot[j] self._last_sed = cur_sed logger.debug("recalculating thetas, freqs, and ss: DONE") with rc_context(app_info.plot_rc_context): self.f.suptitle( "APL-UW Elastic Scattering Model v.2017 - %s - %.1f kHz" % (self.jm2.sed_params.name, cur_freq_khz)) if (self._ss is not None) and plot_spectral: ls = LightSource(135, 40) rgb = ls.shade(self._ss, cmap=cm.autumn, vert_exag=3.0, blend_mode='soft') self.up_ax.plot_surface(x, y, self._ss, rstride=1, cstride=1, alpha=0.4, cmap='Greys', edgecolor='none', shade=False, facecolors=rgb, label='Spectral SS') self.jm2.out.ss_tot += 0.2 freqs_khz = np.full_like(self.jm2.out.ss_tot, self.freq_slider.value()) self.up_ax.plot(self.jm2.out.theta_i, freqs_khz, self.jm2.out.ss_tot, color=self.color_tot, linestyle='-', linewidth=2.0, label="SS at %.1f kHz" % cur_freq_khz) self.up_ax.set_xlim(0.0, 90.0) self.up_ax.set_ylim(1.0, 500.0) self.up_ax.set_zlim(self._pp.db_min, self._pp.db_max) self.up_ax.grid(color=self.color_grid) self.up_ax.set_xlabel('Incidence Angle [deg]') self.up_ax.set_ylabel('Frequency [kHz]') self.up_ax.set_zlabel('Scattering Strength [dB]') # self.up_ax.legend() self.c.draw()