def define_curve_data(cls, a=None, scatter=0.1, n=None, **kwargs): """ Set up the data This method uses the function .. math:: y = a^2 * x * (1 - x) to generate data with a polynom of order 2. Parameters ---------- a: float The parameter to use in the above equation scatter: float The range for the random noise. Random noise will be like ``y * rand * scatter`` where rand is a normally random number between [-1, 1] n: int The number of data points. If None, defaults to the :attr:`default_n` attribute Returns ------- psyplot.data.InteractiveArray The array with the x- and y-data that can serve as an input for the :class:`psyplot.plotter.linreg.LinRegPlotter` """ def func(x, a): return a * a * x * (1 - x) if a is None: a = 1.0434 if n is None: n = cls.default_n x = np.linspace(0, 1, n) y = func(x, a) y += y * np.random.randn(n) * scatter da = psyd.InteractiveList([ xr.DataArray(y, name='y', dims=('x', ), coords={'x': xr.Variable(('x', ), x)}) ]) return da, func
def define_data(cls, slope=None, intercept=None, scatter=0.1, n=None, **kwargs): """Set up the data Parameters ---------- slope: float The slope of the data. If None, defaults to the :attr:`default_slope` attribute intercept: float The y-value for x==0. If None, defaults to the :attr:`default_intercept` attribute scatter: float The range for the random noise. Random noise will be like ``y * rand * scatter`` where rand is a normally random number between [-1, 1] n: int The number of data points. If None, defaults to the :attr:`default_n` attribute Returns ------- xarray.DataArray The array with the x- and y-data that can serve as an input for the :class:`psyplot.plotter.linreg.LinRegPlotter` """ if slope is None: slope = cls.default_slope if intercept is None: intercept = cls.default_intercept if n is None: n = cls.default_n x = np.linspace(0, 10, n) y = intercept + slope * x y += y * np.random.randn(n) * scatter da = xr.DataArray(y, name='y', dims=('x', ), coords={'x': xr.Variable(('x', ), x)}) da.psy.base['v'] = da.x.variable return psyd.InteractiveList([da])
def test_data(self): """Test the :attr:`psyplot.plotter.Formatoption.data` attribute""" class OtherTestPlotter(TestPlotter): fmt4 = SimpleFmt3('fmt4', index_in_list=2) raw_data = psyd.InteractiveList([xr.DataArray([]) for _ in range(4)]) plotter = OtherTestPlotter(raw_data) plotter.plot_data = plot_data = plotter.data.copy(True) copied = plotter.plot_data[2].copy() # -- test the getters self.assertIs(plotter.fmt1.data, plotter.plot_data) self.assertIsNot(plotter.fmt1.data, plotter.data) self.assertIs(plotter.fmt1.raw_data, plotter.data) self.assertIsNot(plotter.fmt1.raw_data, plotter.plot_data) # -- test the setters plotter.fmt4.data = copied self.assertIs(plotter.plot_data[2], copied) self.assertIsNot(plotter.data[2], copied) self.assertIs(plotter.plot_data[1], plot_data[1]) plotter.fmt3.data = raw_data for i, arr in enumerate(plotter.plot_data): self.assertIs(arr, raw_data[i], msg='Wrong array at position %i' % i) # undo the setting plotter.fmt3.data = plot_data # -- test iteration over data # plot data it_data = plotter.fmt3.iter_data for i, arr in enumerate(plotter.fmt3.data): self.assertIs(next(it_data), arr, msg='Wrong array at position %i' % i) # raw data it_data = plotter.fmt3.iter_raw_data for i, arr in enumerate(plotter.fmt3.raw_data): self.assertIs(next(it_data), arr, msg='Wrong raw data array at position %i' % i) self.assertIs(next(plotter.fmt4.iter_data), plot_data[2]) self.assertIs(next(plotter.fmt4.iter_raw_data), raw_data[2])
def test_any_decoder(self): """Test the decoder property with an InteractiveList""" data = psyd.InteractiveList([xr.DataArray([]), xr.DataArray([])]) plot_data = data.copy(True) plot_data.extend([xr.DataArray([]), xr.DataArray([])], new_name=True) for arr in data: arr.psy.init_accessor(decoder=psyd.CFDecoder(arr.psy.base)) plotter = TestPlotter(data) plotter.plot_data = plot_data plot_data = plotter.plot_data # the data might have been copied # test without index in list decoder = psyd.CFDecoder(data[0].psy.base) plotter.fmt2.decoder = decoder for i, d2 in enumerate(plotter.plot_data_decoder): self.assertIs(d2, decoder, msg='Decoder %i has been set wrong!' % i) self.assertEqual(plotter.fmt2.decoder, plotter.plot_data_decoder) self.assertIs(plotter.fmt2.any_decoder, decoder)
def test_data_props_list(self): """Test the data properties of Formatoptions with an InteractiveList""" data = psyd.InteractiveList([xr.DataArray([]), xr.DataArray([])]) plot_data = data.copy(True) plot_data.extend([xr.DataArray([]), xr.DataArray([])], new_name=True) plotter = TestPlotter(data) plotter.plot_data = plot_data plot_data = plotter.plot_data # the data might have been copied self.assertIs(plotter.fmt1.raw_data, data) self.assertIs(plotter.fmt1.data, plot_data) # test with index in list plotter.fmt1.index_in_list = 1 self.assertIs(plotter.fmt1.raw_data, data[1]) self.assertIs(plotter.fmt1.data, plot_data[1]) # test with index in list of plot_data outside raw_data plotter.fmt1.index_in_list = 3 self.assertIs(plotter.fmt1.data, plot_data[3])
def test_decoder_list(self): """Test the decoder property with an InteractiveList""" data = psyd.InteractiveList([xr.DataArray([]), xr.DataArray([])]) plot_data = data.copy(True) plot_data.extend([xr.DataArray([]), xr.DataArray([])], new_name=True) for arr in data: arr.psy.init_accessor(decoder=psyd.CFDecoder(arr.psy.base)) plotter = TestPlotter(data) plotter.plot_data = plot_data plot_data = plotter.plot_data # the data might have been copied self.assertIsInstance(plotter.fmt1.decoder, psyd.CFDecoder) self.assertIs(plotter.fmt1.decoder, data[0].psy.decoder) # test with index in list plotter.fmt1.index_in_list = 1 self.assertIsInstance(plotter.fmt1.decoder, psyd.CFDecoder) self.assertIs(plotter.fmt1.decoder, data[1].psy.decoder) # test without index in list decoder = psyd.CFDecoder(data[0].psy.base) plotter.fmt2.decoder = decoder for i, d2 in enumerate(plotter.plot_data_decoder): self.assertIs(d2, decoder, msg='Decoder %i has been set wrong!' % i) self.assertEqual(plotter.fmt2.decoder, plotter.plot_data_decoder) # test with index in list of plot_data outside raw_data plotter.fmt1.index_in_list = 3 decoder2 = psyd.CFDecoder(data[0].psy.base) plotter.fmt1.decoder = decoder2 for i, d2 in enumerate(plotter.plot_data_decoder): self.assertIs(d2, decoder if i != 3 else decoder2, msg='Decoder %i has been set wrong!' % i) self.assertIsInstance(plotter.fmt1.decoder, psyd.CFDecoder) self.assertIs(plotter.fmt1.decoder, plotter.plot_data_decoder[3])
def test_get_enhanced_attrs_02_list(self): """Test the :meth:`psyplot.plotter.Plotter.get_enhanced_attrs` method """ ds = psyd.open_dataset(bt.get_file('test-t2m-u-v.nc')) plotter = TestPlotter( psyd.InteractiveList( ds.psy.create_list(name=['t2m', 'u'], x=0, t=0))) attrs = {} for key, val in ds.t2m.attrs.items(): attrs['t2m' + key] = val for key, val in ds.u.attrs.items(): attrs['u' + key] = val for key, val in ds.lon.attrs.items(): attrs['x' + key] = val for key, val in ds.lat.attrs.items(): attrs['y' + key] = val attrs['x' + key] = val # overwrite the longitude information # the plot_data has priority over the base variable, therefore we # the plotter should replace the y information with the z information for key, val in ds.lev.attrs.items(): attrs['z' + key] = val attrs['y' + key] = val # overwrite the latitude information for key, val in ds.time.attrs.items(): attrs['t' + key] = val for key in set(ds.t2m.attrs) & set(ds.u.attrs): if ds.t2m.attrs[key] == ds.u.attrs[key]: attrs[key] = ds.t2m.attrs[key] attrs['zname'] = attrs['yname'] = 'lev' attrs['xname'] = 'lat' attrs['tname'] = 'time' attrs['lon'] = attrs['x'] = ds.lon.values[0] attrs['time'] = attrs['t'] = pd.to_datetime( ds.time.values[0]).isoformat() self.maxDiff = None self.assertEqual(dict(plotter.get_enhanced_attrs(plotter.plot_data)), dict(attrs))
def define_poly_data(cls, coeffs=[1, 2, 3], scatter=0.1, n=None, **kwargs): """ Set up the data for a polynomial Parameters ---------- coeffs: list of float The coefficients of the polynomial scatter: float The range for the random noise. Random noise will be like ``y * rand * scatter`` where rand is a normally random number between [-1, 1] n: int The number of data points. If None, defaults to the :attr:`default_n` attribute Returns ------- psyplot.data.InteractiveArray The array with the x- and y-data that can serve as an input for the :class:`psyplot.plotter.linreg.LinRegPlotter` int The degree of the polynomial """ if n is None: n = cls.default_n x = np.linspace(0, 1, n) y = np.poly1d(coeffs)(x) y += y * np.random.randn(n) * scatter da = psyd.InteractiveList([ xr.DataArray(y, name='y', dims=('x', ), coords={'x': xr.Variable(('x', ), x)}) ]) return da, len(coeffs) - 1