def test_unique_columns(self): """Make sure unique_columns gives the expected answers""" a = numpy.array([[1, 1, 1, 0, 0, 0], [0, 1, 1, 1, 0, 0], [0, 1, 1, 1, 0, 0], [1, 1, 1, 0, 0, 0], [1, 1, 1, 1, 1, 0]]) ans1 = numpy.array([[0, 1, 1, 1, 0, 0], [1, 1, 1, 0, 0, 0], [1, 1, 1, 1, 1, 0]]) ans0 = numpy.array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 1], [0, 1, 1, 0, 1], [1, 0, 0, 1, 1], [1, 1, 1, 1, 1]]) numpy.testing.assert_array_equal(ans1, tb.unique_columns(a, axis=1)) numpy.testing.assert_array_equal(ans0, tb.unique_columns(a, axis=0))
def simpleSpectrogram(*args, **kwargs): """ Plot a spectrogram given Z or X,Y,Z. This is a wrapper around pcolormesh() that can handle Y being a 2d array of time dependent bins. Like in the Van Allen Probes HOPE and MagEIS data files. Parameters ========== *args : 1 or 3 arraylike Call Signatures:: simpleSpectrogram(Z, **kwargs) simpleSpectrogram(X, Y, Z, **kwargs) Other Parameters ================ zlog : bool Plot the color with a log colorbar (default: True) ylog : bool Plot the Y axis with a log scale (default: True) alpha : scalar (0-1) The alpha blending value (default: None) cmap : string The name of the colormap to use (default: system default) vmin : float Minimum color value (default: Z.min(), if log non-zero min) vmax : float Maximum color value (default: Z.max()) ax : matplotlib.axes Axes to plot the spectrogram on (default: None - new axes) cb : bool Plot a colorbar (default: True) cbtitle : string Label to go on the colorbar (default: None) Returns ======= ax : matplotlib.axes._subplots.AxesSubplot Matplotlib axes object that the plot is on """ if len(args) not in [1,3]: raise(TypeError("simpleSpectrogram, takes Z or X, Y, Z")) if len(args) == 1: # just Z in, makeup an X and Y Z = np.ma.masked_invalid(np.asarray(args[0])) # make sure not a dmarray or VarCopy X = np.arange(Z.shape[0]+1) Y = np.arange(Z.shape[1]+1) else: # we really want X and Y to be one larger than Z X = np.asarray(args[0]) # make sure not a dmarray or VarCopy Y = np.asarray(args[1]) # make sure not a dmarray or VarCopy Z = np.ma.masked_invalid(np.asarray(args[2])) if X.shape[0] == Z.shape[0]: # same length, expand X X = tb.bin_center_to_edges(X) # hopefully evenly spaced if len(Y.shape) == 1: # 1d, just use as axis Y = tb.bin_center_to_edges(Y) # hopefully evenly spaced elif len(Y.shape) == 2: Y_orig = Y # 2d this is time dependent and thus need to overplot several Y = tb.unique_columns(Y, axis=1) if Y.shape[1] == Z.shape[1]: # hopefully evenly spaced Y_uniq = Y Y_tmp = np.empty((Y.shape[0], Y.shape[1]+1), dtype=Y.dtype) for ii in range(Y.shape[0]): Y_tmp[ii] = tb.bin_center_to_edges(Y[ii]) Y = Y_tmp # deal with all the default keywords zlog = kwargs.pop('zlog', True) ylog = kwargs.pop('ylog', True) alpha = kwargs.pop('alpha', None) cmap = kwargs.pop('cmap', None) vmin = kwargs.pop('vmin', np.min(Z) if not zlog else np.min(Z[np.nonzero(Z)])) vmax = kwargs.pop('vmax', np.max(Z)) ax = kwargs.pop('ax', None) cb = kwargs.pop('cb', True) cbtitle = kwargs.pop('cbtitle', None) # the first case is that X, Y are 1d and Z is 2d, just make the plot if ax is None: fig = plt.figure() ax = fig.add_subplot(111) else: fig = ax.get_figure() Z = Z.filled(0) if len(Y.shape) > 1: for yy in Y_uniq: # which indices in X have these values ind = (yy == Y_orig).all(axis=1) print(Y_orig[ind][0].min(), Y_orig[ind][0].max()) Y_tmp = np.zeros_like(Y_orig) Y_tmp[ind] = Y_orig[ind][0] Z_tmp = np.zeros_like(Z) Z_tmp[ind] = Z[ind] pc = ax.pcolormesh(X, Y_tmp[ind][0], Z_tmp.T, norm=LogNorm(vmin=vmin, vmax=vmax), cmap=cmap, alpha=alpha) else: pc = ax.pcolormesh(X, Y, Z.T, norm=LogNorm(vmin=vmin, vmax=vmax), cmap=cmap, alpha=alpha) if ylog: ax.set_yscale('log') if cb: # add a colorbar cb_ = fig.colorbar(pc) cb_.set_label(cbtitle) return ax
def simpleSpectrogram(*args, **kwargs): """ Plot a spectrogram given Z or X,Y,Z. This is a wrapper around pcolormesh() that can handle Y being a 2d array of time dependent bins. Like in the Van Allen Probes HOPE and MagEIS data files. Parameters ========== *args : 1 or 3 arraylike Call Signatures:: simpleSpectrogram(Z, **kwargs) simpleSpectrogram(X, Y, Z, **kwargs) Other Parameters ================ zlog : bool Plot the color with a log colorbar (default: True) ylog : bool Plot the Y axis with a log scale (default: True) alpha : scalar (0-1) The alpha blending value (default: None) cmap : string The name of the colormap to use (default: system default) vmin : float Minimum color value (default: Z.min(), if log non-zero min) vmax : float Maximum color value (default: Z.max()) ax : matplotlib.axes Axes to plot the spectrogram on (default: None - new axes) cb : bool Plot a colorbar (default: True) cbtitle : string Label to go on the colorbar (default: None) Returns ======= ax : matplotlib.axes._subplots.AxesSubplot Matplotlib axes object that the plot is on """ if len(args) not in [1, 3]: raise (TypeError("simpleSpectrogram, takes Z or X, Y, Z")) if len(args) == 1: # just Z in, makeup an X and Y Z = np.ma.masked_invalid(np.asarray( args[0])) # make sure not a dmarray or VarCopy X = np.arange(Z.shape[0] + 1) Y = np.arange(Z.shape[1] + 1) else: # we really want X and Y to be one larger than Z X = np.asarray(args[0]) # make sure not a dmarray or VarCopy Y = np.asarray(args[1]) # make sure not a dmarray or VarCopy Z = np.ma.masked_invalid(np.asarray(args[2])) if X.shape[0] == Z.shape[0]: # same length, expand X X = tb.bin_center_to_edges(X) # hopefully evenly spaced if len(Y.shape) == 1: # 1d, just use as axis if Y.shape[0] == Z.shape[1]: # same length, expand Y Y = tb.bin_center_to_edges(Y) # hopefully evenly spaced elif len(Y.shape) == 2: Y_orig = Y # 2d this is time dependent and thus need to overplot several Y = tb.unique_columns(Y, axis=1) if Y.shape[1] == Z.shape[1]: # hopefully evenly spaced Y_uniq = Y Y_tmp = np.empty((Y.shape[0], Y.shape[1] + 1), dtype=Y.dtype) for ii in range(Y.shape[0]): Y_tmp[ii] = tb.bin_center_to_edges(Y[ii]) Y = Y_tmp # deal with all the default keywords zlog = kwargs.pop('zlog', True) ylog = kwargs.pop('ylog', True) alpha = kwargs.pop('alpha', None) cmap = kwargs.pop('cmap', None) vmin = kwargs.pop('vmin', np.min(Z) if not zlog else np.min(Z[np.nonzero(Z)])) vmax = kwargs.pop('vmax', np.max(Z)) ax = kwargs.pop('ax', None) cb = kwargs.pop('cb', True) cbtitle = kwargs.pop('cbtitle', None) # the first case is that X, Y are 1d and Z is 2d, just make the plot if ax is None: fig = plt.figure() ax = fig.add_subplot(111) else: fig = ax.get_figure() Z = Z.filled(0) if len(Y.shape) > 1: for yy in Y_uniq: # which indices in X have these values ind = (yy == Y_orig).all(axis=1) print(Y_orig[ind][0].min(), Y_orig[ind][0].max()) Y_tmp = np.zeros_like(Y_orig) Y_tmp[ind] = Y_orig[ind][0] Z_tmp = np.zeros_like(Z) Z_tmp[ind] = Z[ind] pc = ax.pcolormesh(X, Y_tmp[ind][0], Z_tmp.T, norm=LogNorm(vmin=vmin, vmax=vmax), cmap=cmap, alpha=alpha) else: pc = ax.pcolormesh(X, Y, Z.T, norm=LogNorm(vmin=vmin, vmax=vmax), cmap=cmap, alpha=alpha) if ylog: ax.set_yscale('log') if cb: # add a colorbar cb_ = fig.colorbar(pc) if cbtitle is not None: cb_.set_label(cbtitle) return ax