Source code for vifpara.views.plot_over_time

import os
from typing import List
import paraview.simple as pv

from ..logging import logger
from ..other import Vector3
from ..base import Case, Layout, Config
from . import IViewObject


[docs] class PlotOverTime(IViewObject): def __init__(self, case: Case, probe_point: Vector3, fields: list[str] = [], height: int = 135): """ Initialize a PlotOverTime view for sampling scalar fields at a single point and rendering an XY chart representation over a time sequence. The PlotOverTime view element can be used to display how scalar fields evolve over time at a specific point probe location inside your case. You can embed this chart into a layout cell, and you can also export the underlying sampled values as a CSV file. This class enables: - Sampling multiple scalar fields at a specific point in 3D space. - Rendering the sampled temporal data in a ParaView XY chart. - Exporting the underlying sampled values as CSV. :param Case case: The evaluated case from which the field data is extracted. :param Vector3 probe_point: The point in space at which scalar fields are sampled. :param list[str] fields: The scalar field names to extract and plot over time. :param int height: The height of the view representation inside the layout. :return: None """ super().__init__(case, 263, height, False) self._case = case self._probe_point = probe_point self._fields: List[str] = fields self._render_fields: List[str] = fields self._case.get_case().UpdatePipeline() # Convert cell data to point data to make probing/interpolation reliable. self._c2p = pv.CellDatatoPointData(Input=self._case.get_case()) self._c2p.PassCellData = 1 # ProbeLocation samples/interpolates arrays at an arbitrary 3D coordinate. self._probe = pv.ProbeLocation(registrationName='ProbeLocation1', Input=self._c2p) self._probe.ProbeType.Center = self._probe_point.to_list() # PlotDataOverTime produces an XY table of probed values across time steps. self._plot_over_time_obj = pv.PlotDataOverTime(registrationName='PlotOverTime1', Input=self._probe) self._render_view = pv.CreateView('XYChartView') self._display = pv.Show(self._plot_over_time_obj, self._render_view, 'XYChartRepresentation') visible_series: list = self._generate_visible_series() self._display.SeriesVisibility = visible_series self._fields = visible_series def _generate_visible_series(self) -> list: visible_series: list = [] for series in self._display.SeriesVisibility: # max, avg, min, ... are all the same since we probe only a 1d point. if "avg(" in series: series_allowed: bool = self._check_series_allowed(series) if series_allowed: visible_series.append(series) return visible_series def _check_series_allowed(self, series_name: str) -> bool: if len(self._render_fields) == 0: return True for field in self._fields: if f"({field} " in series_name or f"({field})" in series_name: return True return False def _render_inside(self, layout: Layout, row: int=0, col: int=0): logger.info(f"Rendering plot over time to <{row}|{col}>.") layout.add_render_view(row, col, self) def get_render_object(self): return self._plot_over_time_obj def export_as_csv(self, config: Config, filename: str): full_path: str = config.get_plot_path() + filename + ".csv" logger.info(f"Saving plot to file {full_path}.") fields = self._fields.copy() pv.SaveData(full_path, proxy=self._plot_over_time_obj, ChooseArraysToWrite=1, PointDataArrays=fields, AddMetaData=0)