def test_colormap(): viridis = plt.get_cmap('viridis') cmap = ColorPalette.fromColorMap('viridis', np.arange(0, 10), np.arange(1, 11), viridis) zero_value = np.array( [0.26666666666666666, 0.00392156862745098, 0.32941176470588235, 1.0]) ten_value = np.array( [0.9921568627450981, 0.9058823529411765, 0.1450980392156863, 1.0]) np.testing.assert_almost_equal(cmap.getDataColor(0), zero_value) np.testing.assert_almost_equal(cmap.getDataColor(10), ten_value) viridis = plt.get_cmap('viridis') cmap = ColorPalette.fromColorMap('viridis', np.arange(-4, 5), np.arange(-3, 6), viridis, is_log=True) dcolor = cmap.getDataColor(np.exp(-4.0)) tcolor = np.array( (0.26666666666666666, 0.00392156862745098, 0.32941176470588235, 1.0)) np.testing.assert_almost_equal(dcolor, tcolor)
def test_cpt(): rm = 100 # number of lines to remove on black end of magma_r # how much at the zero end should be *just* white before transitioning to # meet colors ad = 50 magma_cpt = cm.get_cmap('magma_r', 512) # start with magma_r white_bit = np.array([255 / 256, 250 / 256, 250 / 256, 1]) # create array of white slip_cpt = magma_cpt(np.linspace(0, 1, 512)) # initialize slip_cpt # move beginning up to remove black end slip_cpt[rm:, :] = slip_cpt[0:-rm, :] # gradient from white to beginning of new magma r_s = np.linspace(white_bit[0], slip_cpt[rm][0], rm - ad) g_s = np.linspace(white_bit[1], slip_cpt[rm][1], rm - ad) b_s = np.linspace(white_bit[2], slip_cpt[rm][2], rm - ad) slip_cpt[ad:rm, :][:, 0] = r_s slip_cpt[ad:rm, :][:, 1] = g_s slip_cpt[ad:rm, :][:, 2] = b_s slip_cpt[:ad, :] = white_bit slipmap = ListedColormap(slip_cpt) z0 = np.arange(0, 300, 1) z1 = np.arange(1, 301, 1) ncolors = 64 resolution = (z1.max() - z0.min()) / ncolors name = 'test' cpt = ColorPalette.fromColorMap(name, z0, z1, slipmap, resolution=resolution) try: tdir = tempfile.mkdtemp() tfile = os.path.join(tdir, 'test.cpt') cpt.write(tfile) cpt2 = ColorPalette.fromFile(tfile) np.testing.assert_almost_equal( cpt.getDataColor(150)[0], cpt2.getDataColor(150)[0]) except: pass finally: if os.path.isdir(tdir): shutil.rmtree(tdir)
def _create_palette(imtype, levels): """Create a ColorPalette object from given levels and IMT type. Args: imtype (str): One of 'PGV','PGA','SA(0.3)',etc. levels (sequence): Sequence of contour levels. Returns: ColorPalette: ColorPalette using range of input data and IMT_CMAP. """ # this method assumes that levels are in logspace if len(levels) > 1: if len(levels) % 2: levels.append(levels[-1]) nsteps = 256 z0 = np.linspace(np.log(levels[0]), np.log(levels[-2]), nsteps) z1 = np.linspace(np.log(levels[1]), np.log(levels[-1]), nsteps) else: z0 = np.array([levels[0], levels[0]*10]) z1 = np.array([levels[0], levels[0]*10]) cmap = plt.get_cmap(IMT_CMAP) palette = ColorPalette.fromColorMap(imtype, z0, z1, cmap, is_log=True) return palette
def plot_regression(event_table, imc, imc_table, imt, filename, distance_metric='EpicentralDistance', colormap='viridis'): """Make summary "regression" plot. TODO: * Add GMPE curve and compute mean/sd for all the observations and then also report the standardized residuals. * Better definitions of column names and units. """ fig = plt.figure(figsize=(10, 5)) # ax = plt.subplot(1, 1, 1) ax = fig.add_axes([BOTTOM, AX1_LEFT, AX1_WIDTH, AX1_HEIGHT]) if distance_metric not in imc_table.columns: raise KeyError('Distance metric "%s" not found in table' % distance_metric) imt = imt.upper() # Stupid hack to get units for now. Need a better, more systematic # approach if imt.startswith("SA") | (imt == "PGA"): units = "%g" elif imt.startswith('FAS') or imt in ['ARIAS', 'PGV']: units = "cm/s" else: units = 'Unknown units for IMT %s' % imt if imt not in imc_table.columns: raise KeyError('IMT "%s" not found in table' % imt) # get the event information # group imt data by event id # plot imts by event using colors banded by magnitude eventids = event_table['id'] # set up the color bands minmag = event_table['magnitude'].min() min_mag = min(np.floor(minmag / DELTA_MAG) * DELTA_MAG, MIN_MAG) maxmag = event_table['magnitude'].max() max_mag = max(np.ceil(maxmag / DELTA_MAG) * DELTA_MAG, MAX_MAG) z0 = np.arange(min_mag, max_mag, 0.5) z1 = np.arange(min_mag + DELTA_MAG, max_mag + DELTA_MAG, DELTA_MAG) cmap = plt.get_cmap(colormap) palette = ColorPalette.fromColorMap('mag', z0, z1, cmap) colors = [] for zval in np.arange(min_mag, max_mag + 0.5, 0.5): tcolor = palette.getDataColor(zval, 'hex') colors.append(tcolor) cmap2 = mpl.colors.ListedColormap(colors) for eventid in eventids: emag = event_table[event_table['id'] == eventid].magnitude.to_numpy()[0] norm_mag = (emag - min_mag) / (max_mag - min_mag) color = cmap2(norm_mag) erows = imc_table[imc_table['EarthquakeId'] == eventid] distance = erows[distance_metric] imtdata = erows[imt] ax.loglog(distance, imtdata, mfc=color, mec='k', marker='o', linestyle='None') ax.set_xlabel('%s (km)' % distance_metric) ax.set_ylabel('%s (%s)' % (imt, units)) bounds = np.arange(min_mag, max_mag + 1.0, 0.5) norm = mpl.colors.BoundaryNorm(bounds, cmap2.N) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="3%", pad=0.05) mpl.colorbar.ColorbarBase( cax, cmap=cmap2, norm=norm, ticks=bounds, # optional spacing='proportional', orientation='vertical') plt.sca(ax) plt.suptitle('%s vs %s (#eqks=%i)' % (distance_metric, imt, len(eventids))) plt.title('for component %s' % (imc)) plt.savefig(filename)
def plot_regression( event_table, imc, imc_table, imt, filename, distance_metric="EpicentralDistance", colormap="viridis", ): """Make summary "regression" plot. TODO: * Add GMPE curve and compute mean/sd for all the observations and then also report the standardized residuals. * Better definitions of column names and units. """ fig = plt.figure(figsize=(10, 5)) ax = fig.add_axes([BOTTOM, AX1_LEFT, AX1_WIDTH, AX1_HEIGHT]) if distance_metric not in imc_table.columns: raise KeyError( f'Distance metric "{distance_metric}" not found in table') imt = imt.upper() # Stupid hack to get units for now. Need a better, more systematic # approach if imt.startswith("SA") | (imt == "PGA"): units = "%g" elif imt.startswith("FAS") or imt in ["ARIAS", "PGV"]: units = "cm/s" else: units = f"Unknown units for IMT {imt}" if imt not in imc_table.columns: raise KeyError(f'IMT "{imt}" not found in table') # get the event information # group imt data by event id # plot imts by event using colors banded by magnitude eventids = event_table["id"] # set up the color bands minmag = event_table["magnitude"].min() min_mag = min(np.floor(minmag / DELTA_MAG) * DELTA_MAG, MIN_MAG) maxmag = event_table["magnitude"].max() max_mag = max(np.ceil(maxmag / DELTA_MAG) * DELTA_MAG, MAX_MAG) z0 = np.arange(min_mag, max_mag, 0.5) z1 = np.arange(min_mag + DELTA_MAG, max_mag + DELTA_MAG, DELTA_MAG) cmap = plt.get_cmap(colormap) palette = ColorPalette.fromColorMap("mag", z0, z1, cmap) colors = [] for zval in np.arange(min_mag, max_mag + 0.5, 0.5): tcolor = palette.getDataColor(zval, "hex") colors.append(tcolor) cmap2 = mpl.colors.ListedColormap(colors) for eventid in eventids: emag = event_table[event_table["id"] == eventid].magnitude.to_numpy()[0] norm_mag = (emag - min_mag) / (max_mag - min_mag) color = cmap2(norm_mag) erows = imc_table[imc_table["EarthquakeId"] == eventid] distance = erows[distance_metric] imtdata = erows[imt] ax.loglog(distance, imtdata, mfc=color, mec="k", marker="o", linestyle="None") ax.set_xlabel(f"{distance_metric} (km)") ax.set_ylabel(f"{imt} ({units})") bounds = np.arange(min_mag, max_mag + 1.0, 0.5) norm = mpl.colors.BoundaryNorm(bounds, cmap2.N) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="3%", pad=0.05) mpl.colorbar.ColorbarBase( cax, cmap=cmap2, norm=norm, ticks=bounds, # optional spacing="proportional", orientation="vertical", ) plt.sca(ax) plt.suptitle("%s vs %s (#eqks=%i)" % (distance_metric, imt, len(eventids))) plt.title(f"for component {imc}") plt.savefig(filename)