def plot(self, ax: Ax, test=False) -> Union[Tuple[Ax, Artists], Tuple[Tuple[Ax, Ax], Tuple[Artists, Artists]]]: """ pyplot.axsubplot -> pyplot.axsubplot Apply plot action functions to axes. Parameters ---------- ax: matplotlib.axes._subplot.Axes test: bool, optional Flag for test plot mode. Default value is False. Return ------ plotted_ax: matplotlib.axes._subplot.Axes | Tuple[matplotlib.axes._subplot.Axes] Axes applied the plot actions. """ self.set_test_mode(test) first_plot_actions: Iterable[PlotAction] = map( self.__get_PlotAction, filter(lambda i: not self.is_second_axes[i], range(len(self))) ) first_axis_style = self.get_first_axis_style() ax1, artists1 = pip( self.plotter(first_plot_actions, first_axis_style), self.show_title, self.setXaxisFormat() )((ax, [])) if any(self.is_second_axes): second_axis_actions: Iterable[PlotAction] = map( self.__get_PlotAction, filter( lambda i: self.is_second_axes[i], range(len(self))) ) second_xaxis_style = {**self.get_second_axis_style()} second_yaxis_style = {**self.get_second_axis_style()} # A hack for changing the first and the second axis limits independently. ax2, artists2 = pip( lambda ax: (ax[0].twiny(), ax[1]), self.plotter([], second_xaxis_style), lambda ax: (ax[0].twinx(), ax[1]), self.plotter(second_axis_actions, second_yaxis_style) )((ax1, [])) return ((ax1, ax2), (artists1, artists2)) else: return (ax1, artists1)
def files(self, verbose=False): return pip( it.filtering(os.path.isfile), list, tee( pip( enumerate, list, print if verbose else identity ) ) )(self.paths)
def read(self, i) -> Duplicated[pd.DataFrame]: """ Indipendent from type of data source. """ data: Duplicated = wrap_by_duplicate(self.data[i]) meta: Duplicated = wrap_by_duplicate(self.dataInfo[i]) default_transformers: Duplicated = self.default_transformers(i) data_transformers: Duplicated = wrap_by_duplicate( self.dataTransformer[i]) max_len = pip( it.mapping(len), it.reducing(lambda acc, e: acc if acc > e else e)(0) )([data, meta, default_transformers, data_transformers]) dfs = [] for j in range(max_len): d = get_from_duplicated(data, j, {}) m = get_from_duplicated(meta, j, {}) def_trans = get_from_duplicated(default_transformers, j, []) trans = get_from_duplicated(data_transformers, j, []) Loader = ISubplot.IDataLoader(d, self.isTest()) if self.isTest(): transformers = None else: transformers = def_trans + trans dfs.append(Loader.read(d, meta=m, transformers=transformers)) return Duplicated(*dfs)
def read(self, i) -> Tuple[pd.DataFrame]: """ Indipendent from type of data source. """ data: tuple = wrap_by_tuple(self.data[i]) meta: tuple = wrap_by_tuple(self.dataInfo[i]) default_transformers: tuple = self.default_transformers(i) data_transformers: tuple = wrap_by_tuple(self.dataTransformer[i]) max_len = pip(it.mapping(len), it.reducing(lambda acc, e: acc if acc > e else e)(0))([ data, meta, default_transformers, data_transformers ]) def get_with_duplicate(it, i, default=None): if len(it) is 0: return default return it[i] if len(it) > i else it[-1] dfs = [] for j in range(max_len): d = get_with_duplicate(data, j, {}) m = get_with_duplicate(meta, j, {}) def_trans = get_with_duplicate(default_transformers, j, []) trans = get_with_duplicate(data_transformers, j, []) loader = ISubplot.IDataLoader(d, self.isTest()) if self.isTest(): transformers = None else: transformers = def_trans + trans dfs.append(loader.read(d, meta=m, transformers=transformers)) return tuple(dfs)
def genMaintenanceBox(maintenancePeriods: List[IPeriod_with_window], **kwargs): """ Parameters ---------- maintenancePeriods: List[str] メンテナンスの開始日時と終了日時を表す文字列のリスト. Returns ------- maintenancePlot: Callable Dict -> pandas.DataFrame -> ax -> ax メンテナンス期間を表す長方形をプロットするためのアクション. Example ------- from src.plot_util import Figure from src.setting import default, maintenance from src.plot_maintenance import getMaintenanceBox, presetSubplot maintenanceBox = genMaintenanceBox(*maintenance["st1-1"]) figure = Figure() figure.add_subplot( presetSubplot(default)( name, fileSelector=[site], plot=[*maintenanceBox] ) ) figure.show() """ return bandPlot( pip( it.mapping(lambda p: p.get_period()[0] if isinstance(p, IPeriod_with_window) else p), it.mapping(pd.to_datetime), tuple)(maintenancePeriods), ** kwargs) if len(maintenancePeriods) > 0 else bandPlot([None])
def getFileList(*patterns): return lambda dirPath: pip( getAllSubPath, it.filtering(isMatchAll(patterns)), list, PathList )(dirPath)
def read_original_dat(meta: VectorReadOption, common, sep=",", preprocess=[timeShifter]): files = PathList.match(r"\.dat$")(meta.read_directory).files(verbose=True) dfs = [] for file in files: reader = pd.read_csv(file, sep=sep, chunksize=50000, names=common["columns"], header=meta.header_row) df = pd.concat( pip(*[f(meta, common) for f in preprocess])(r) for r in tqdm(reader)) display(df.head(10)) dfs.append(df) df = pd.concat(dfs) df_droped = df.drop(common["drop"], axis=1) return df_droped
def __getPlotAction(self, i): dfs: tuple = self.read(i) opt = self.get_option(i) if len(dfs) == 0 or all(map(lambda df: len(df) is 0, dfs)): return Subplot.__noDataAx return lambda ax: pip(*[f(dfs, opt) for f in self.plotMethods[i]], )(ax)
def directory_from(*roots): map_get_paths = it.mapping(pip( getAllSubPath, it.filtering(isMatchAll(patterns)), )) def concat(acc, e): return [*acc, *e] return PathList(it.reducing(concat)([])(map_get_paths(roots)))
def generate(site: SiteObject, machineNames: List[str], limit={}, style={}, saveDir=None, file=""): subplotStyle = { **default.get_axes_style(), "xFmt": "%m/%d\n%H:%M", **style } unique_maintenance_date_pairs = pip( it.mapping(lambda so: so.get_date_pairs_of_maintenance()), it.mapping(lambda pairs: it.reducing( lambda acc, e: [*acc, e] if e not in acc else acc)([])(pairs)), it.reducing(lambda acc, e: [*acc, *it.filtering(lambda v: v not in acc)(e)])([]), lambda dates: sorted( dates, key=lambda item: pd.to_datetime(item[0])))([site]) returns = [] for start_date, end_date in unique_maintenance_date_pairs: subplotLimit = { "xlim": site.get_maintenance([start_date], [end_date])[0].get_period()[1], **limit } figure = Figure() for name in machineNames: maintenanceBox = genMaintenanceBox( site.get_maintenance([start_date], [end_date], key=name)) figure.add_subplot(presetSubplot(default)( name, fileSelector=site.get_file_selector(), plot=[maintenanceBox], style=subplotStyle, limit=subplotLimit), names=name) save = save_plot( "./image/" + site.get_name() + "/" if saveDir == None else saveDir, f'{site.get_name()+file}-maintenance-{start_date}-{end_date}') returns.append((figure, save, [maintenanceBox], { "style": subplotStyle, "limit": subplotLimit })) return returns
def plot(self, ax, test=False): """ pyplot.axsubplot -> pyplot.axsubplot Apply plot action functions to ax. Parameters ---------- ax: pyplot.axsubplot test: bool, optional Flag for test plot mode. Default value is False. Return ------ plotted_ax: pyplot.axsubplot Ax applied the plot actions. """ self.set_test_mode(test) actions1 = map( self.__getPlotAction, filter(lambda i: not self.is_second_axes[i], range(self.length))) ax1 = pip(self.plotter(actions1, self.axes_style), self.show_title, self.setXaxisFormat())(ax) if any(self.is_second_axes): actions2 = map( self.__getPlotAction, filter(lambda i: self.is_second_axes[i], range(self.length))) style2, _ = mix_dict(self.axes_style, self.diff_second_axes_style) ax2 = pip(lambda ax: ax.twiny(), self.plotter([], style2), lambda ax: ax.twinx(), self.plotter(actions2, style2))(ax1) return (ax1, ax2) else: return ax1
def rose( data: DataSource, x, # factor1 selector y: str, # stack factor selector yagg, # aggregate *arg, width=None, color=None, cmap=None, xfactor=None, # explicit factor list norm=False, **kwargs): x_factor_series, x_factor, position = Iget_factor(data, x, xfactor) x_group = data.groupby( pd.Categorical(x_factor_series, ordered=True, categories=x_factor)) subset_for_x_factor = [ data.loc[x_group.groups[xfname]] for xfname in x_factor ] # aggrigation時にnanがあると, normalize時にsumがnanになる. # それを回避するためにfillna(0)してある. heights = pip(it.mapping(lambda df: yagg(df[y].fillna(0))), pd.Series)(subset_for_x_factor) colors = pip(it.mapping(lambda df: get_literal_or_series(color, df)), pd.Series)(subset_for_x_factor) if norm: sum = np.sum(heights) heights = heights.apply(lambda height: 0 if sum == 0 else height / sum) plot_arg = {"width": width, "color": colors, **kwargs} @gen_plotter def plot(ax): return ax.bar(position, heights, **plot_arg) return plot
def to_XY_coordinate(x_direction, y_direction, xname="X_converted", yname="Y_converted"): old_coordinate = basis_by_North(0, 90) new_coordinate = basis_by_North(x_direction, y_direction) return lambda df: pip( vectors_from_dataframe("Vel NS[cm/s]", "Vel EW[cm/s]"), lambda vectors: map(transform_coordinate(new_coordinate, old_coordinate), vectors), list, dataframe_from_vectors(columns=[xname, yname], index=df.index))(df)
def detect_encoding(self, path: str, header: int): with open(path, mode='rb') as f: detector = UniversalDetector() i = 0 lines = [] for line in f: if (i >= header or detector.done): break detector.feed(line) lines.append(line) i = i + 1 detector.close() encoding = detector.result['encoding'] if detector.result[ 'encoding'] != None else "shift-JIS" if self.is_verbose: pip(enumerate, it.mapping(lambda t: (t[0], str(t[1], encoding=encoding))), list, display)(lines) return encoding
def __show_custom(self, matpos: Matpos, subgrids: List[Subgrid], padding={}, test=False, **kwargs)->Tuple[Figure, List[Ax]]: fig, empty_axes = matpos.figure_and_axes( subgrids, padding=padding, **kwargs ) axes = pip( Figure.__applyForEach(test), list )(zip(empty_axes, self.subplots)) return (fig, dict(zip(self.axIdentifier, axes)))
def get_averaged_scale(self, period_filter): energy = self.feature.amplitude**2 selector = find(period_filter(self.get_periods())) interval = self.feature.dj * self.feature.dt cdelta = self.feature.mother.cdelta return pip( lambda scales: scales.transpose(), lambda scales: self.get_power() / scales, lambda scales: scales[selector, :].sum(axis=0), lambda global_scale: energy * interval * global_scale / cdelta)( self.get_scales() * np.ones((self.feature.N, 1)))
def __init__(self, t: VectorD, signal: VectorD, detrend: bool = True, verbose: bool = False) -> None: """ Construct instance for operating and plotting Parameters ========== t: [float] list like ofject Time series for signal. signal: [float] list like ofject Signal. detrend: bool, optional If true, signal is detrended. Default is true. verbose: bool, optional If true, you can get more information. Default is False. Example ======= t = numpy.arange(100) x = genSignal(t) cwt = CWT(t,x) Example ======= CWT(t,x)\ .setTimeInterval(dt)\ .setMinimumScale(dt*2)\ .setSubOctave(1/2)\ .setNumberOfScale()\ .setMotherWavelet(wavelet.Morlet(6))\ .auto()\ .plot() """ self.t = t self.signal = signal self.dat_norm, std = pip(CWT.detrend if detrend else identity, CWT.normalized)(signal) self.period_filter = lambda period: np.array([True for v in period]) self.verbose = verbose self.feature = WaveletSettings(signal_length=len(signal), amplitude=std) self.threshold = 0.95
def _get_periods( storage: IPeriodStorage, start_dates: Optional[List[str]] = None, end_dates: Optional[List[str]] = None ) -> List[IPeriod_with_window]: start_date_filter = it.filtering(lambda p: p.get_start_date( ) in start_dates) if start_dates is not None else identity end_date_filter = it.filtering(lambda p: p.get_end_date() in end_dates ) if end_dates is not None else identity return pip(start_date_filter, end_date_filter, list)(storage.get_periods())
def assemble(self, *preprocesses) -> pd.DataFrame: """ Cocatenate all chunks preprocessed by some functions. DataFrame is created only after calling this method. Parameters ---------- preprocesses: callable[[pandas.DataFrame], pandas.DataFrame] Functions for modifying pandas.DataFrame. Default is Identity function (no modification). """ preprocessor = pip( *preprocesses) if len(preprocesses) > 0 else identity print(f"reading...[{self.path}]") df = preprocessor(self.reader) return df
def figure_and_axes(self, subgrid_names: List[str] = None, padding: dict | list = {}, figsize: Optional[Size] = None, dpi: Optional[int] = None, **figure_kwargs) -> Tuple[Fig, List[Ax]]: """ Generate matplotlib.pyplot.figure and its subplots of matplotlib.pyplot.axsubplot. This method also takes key word arguments same with matplotlib.pyplot.figure. Paraeters --------- subgrids: list[Subgrid] List of Subgrids generated by this instance. padding: dict, optional Dictionary to overwrite default padding size around plot areas of subplots. It can have keys "top", "left", "bottom", and "right. If padding are too small, axises may be out of image. Default value is empty dictionaly. figsize: tuple(float), optional Tuple with 2 float number (width, height) to overwrite figure size. Default value is None. kwargs: Key word arguments compatible to matplotlib.pyplot.figure. Return ------ fig: matplotlib.figure.Figure axs: list[matplotlib.axes._subplots.AxesSubplot] """ subgrids = self.get_subgrids( subgrid_names ) if subgrid_names is not None else self.get_all_subgrids() fig = plt.figure( figsize=self.get_size() if figsize is None else figsize, dpi=self.dpi, **dict(self.default_figure_style, **figure_kwargs)) axs = pip(mapping(self.generate_axes(fig, padding)), list)(subgrids) return (fig, axs)
def assemble(self, *preprocesses): """ Cocatenate all chunks preprocessed by some functions. DataFrame is created only after calling this method. Parameters ---------- preprocesses: callable[[pandas.DataFrame], pandas.DataFrame] Functions for modifying pandas.DataFrame. Default is Identity function (no modification). """ preprocessor = pip( *preprocesses) if len(preprocesses) > 0 else identity with tqdm(self.reader) as _tqdm: _tqdm.set_postfix(path=self.path) self.df = pd.concat(preprocessor(r) for r in _tqdm) self.indexRange = [self.df.index.min(), self.df.index.max()] return self
def plotter(actions, style): return pip( plot.set_cycler(style["cycler"]), *actions, plot.axis_scale()({}, style["scale"]), plot.set_tick_parameters(axis="both")({}, style["tick"]), plot.set_tick_parameters(axis="x")({}, { **style["tick"], **style["xtick"] }), plot.set_tick_parameters(axis="y")({}, { **style["tick"], **style["ytick"] }), plot.set_xlim()({}, { "xlim": style["xlim"] }), plot.set_ylim()({}, { "ylim": style["ylim"] }), plot.set_label()({}, style["label"]), plot.set_grid()({}, style["grid"]))
def plotter(actions: Iterable[PlotAction], style: dict) -> PlotAction: """ Plot actions for setting axes style * cycler * axis scale * axis range * axis ticks * axis labels * axis grids """ style_setters = [ plot_action.axis_scale()({}, style["scale"]), plot_action.set_xlim()({}, {"xlim": style["xlim"]}), plot_action.set_ylim()({}, {"ylim": style["ylim"]}), plot_action.set_zlim()({}, {"zlim": style["zlim"]}), plot_action.set_tick_parameters(axis="both")( {}, style["tick"]), plot_action.set_tick_parameters(axis="x")( {}, {**style["tick"], **style["xtick"]}), plot_action.set_tick_parameters(axis="y")( {}, {**style["tick"], **style["ytick"]}), plot_action.set_tick_parameters(axis="z")( {}, {**style["tick"], **style["ytick"]}), plot_action.set_xlabel()( {}, {**style["label"], **style["xlabel"]}), plot_action.set_ylabel()( {}, {**style["label"], **style["ylabel"]}), plot_action.set_zlabel()( {}, {**style["label"], **style["zlabel"]}), plot_action.set_grid()({}, style["grid"]) ] return pip( plot_action.set_cycler(style["cycler"]), *actions, *style_setters )
def __get_PlotAction(self, i) -> PlotAction: df: Duplicated = self.read(i) opt = self.get_option(i) if len(df) == 0: return Subplot.__action_plot_nothing if all(map(lambda df: df is not None and len(df) == 0, self.data)): return Subplot.__action_plot_nothing def switch_by_func_type(f, data, option): if is_PlotAction(f): return f if is_unary(f): return f if is_binary(f): return f(data, option) else: raise TypeError( "function for plot option must be at least unary or binary function.") return lambda ax: pip( *[switch_by_func_type(_plot, df, opt) for _plot in self.plotMethods[i]], )(ax)
pip( plot.line()(moc, { "x": "x", "y": ("y"), }), plot.scatter()(moc, { "y": ("x", "y", "z"), "ylim": [-20, 20], "x": "x", "c": "white", "edgecolors": ("red", "green", "blue"), "s": 100, "linewidth": 1, "linestyle": ("-", "--") }), plot.vlines()( moc, { "lower": (0, -10) }, x="x", y=("y", "z"), ), plot.yband(xpos=([-0.5, 0.5], [1, 1.5]))(moc, { "y": ["y", "z"], "hatch": "x" }), plot.yband(xpos=([-0.5, 0.5], [1, 1.5]))(moc, { "y": ("y", "z"), "color": "red" }), plot.xband()(moc, { "x": "x", "y": "y", "ypos": [5, 5.5], "color": "blue", "xlim": [None, 10] }), plot.set_tick_parameters()(moc, axis="x", labelsize=20, rotation=90), plot.set_label()(moc, ylabel="Y\nlabel", fontsize=24), plot.set_xlim()(moc, x="x"), plot.set_ylim()(moc, { "y": ["y", "z"], "ylim": None }), plot.axis_scale()({}))(plt.subplot())
def get_confidential_set(self, dAIC_threshold): return pip(set_dAIC, select_dAIC_lt(dAIC_threshold), set_Akaike_weight)(self.models.sort_values("AIC"))
def read(source, meta={}, transformers=[identity]): return pip(*transformers)(pd.DataFrame(source))
def assemble(self, *preprocesses: DataFrame_transformer): preprocessor = pip(*preprocesses) if preprocesses else identity self.df = preprocessor(self.reader) return self
def generate(site_objects: List[SiteObject], machineName: str, limit={}, style={}, saveDir=None, file=""): subplotStyle = { **default.get_axes_style(), "xFmt": "%m/%d\n%H:%M", **style } unique_maintenance_date_pairs = pip( it.mapping(lambda so: so.get_date_pairs_of_maintenance()), it.mapping(lambda pairs: it.reducing( lambda acc, e: [*acc, e] if e not in acc else acc)([])(pairs)), it.reducing(lambda acc, e: [*acc, *it.filtering(lambda v: v not in acc)(e)])([]), lambda dates: sorted( dates, key=lambda item: pd.to_datetime(item[0])))(site_objects) returns = [] for start_date, end_date in unique_maintenance_date_pairs: figure = Figure() # siteごとにメンテナンスの回数が異なる. subplotLimit = { "xlim": pip( it.mapping(lambda so: so.get_maintenance([start_date], [end_date])), it.filtering(lambda p: len(p) > 0), list)(site_objects)[0][0].get_period()[1], **limit } for so in site_objects: maintenanceBox = genMaintenanceBox( so.get_maintenance([start_date], [end_date], key=machineName)) figure.add_subplot(presetSubplot(default)( machineName, fileSelector=so.get_file_selector(), plot=[maintenanceBox], option={}, ylabel=so.get_name(), style=subplotStyle, limit=subplotLimit), names=machineName + "-" + so.get_name()) save = save_plot( f'./image/{machineName if saveDir is None else saveDir}/', f'{machineName}{file}-maintenance-{start_date}-{end_date}') returns.append((figure, save, { "style": subplotStyle, "limit": subplotLimit })) return returns
def get_date_pairs(self) -> List[Tuple[str, str]]: return pip( it.mapping(lambda p: (p.get_start_date(), p.get_end_date())), list)(self.get_periods())