Beispiel #1
0
    def plotfig_subregions(self, prop, **kwargs):
        """Plot a property within all subregions (by default, vs. time).

        **Arguments:**

        - *prop*: Name of the property

             This will be appended to the names of the subregions (separated by
             '.') in order to determine the names of the variables to plot on
             the primary y axis.

        - *\*\*kwargs*: Additional arguments for  :meth:`modelicares.plot` (and thus to
          :meth:`modelicares.base.plot` and finally to
          :meth:`matplotlib.pyplot.plot`)
        """
        # Generate reasonable defaults.
        title = kwargs.pop('title', "%s within Subregions" % prop)
        label = kwargs.pop('label', "subregion_prop_%s" % prop)
        ynames1 = kwargs.pop('ynames1', flatten_list(self.subregions_w_prop(prop)))
        default_legends1 = [subregion.replace('.subregions', "")
                            for subregion in flatten_list(self.rel_subregions)]
        legends1 = kwargs.pop('legends1', default_legends1)

        # Create the plot.
        self.plotfig(title=title, label=label, ynames1=ynames1,
                     legends1=legends1, **kwargs)
Beispiel #2
0
    def plotfig_subregions(self, prop, **kwargs):
        """Plot a property within all subregions (by default, vs. time).

        **Arguments:**

        - *prop*: Name of the property

             This will be appended to the names of the subregions (separated by
             '.') in order to determine the names of the variables to plot on
             the primary y axis.

        - *\*\*kwargs*: Additional arguments for  :meth:`modelicares.plot` (and thus to
          :meth:`modelicares.base.plot` and finally to
          :meth:`matplotlib.pyplot.plot`)
        """
        # Generate reasonable defaults.
        title = kwargs.pop('title', "%s within Subregions" % prop)
        label = kwargs.pop('label', "subregion_prop_%s" % prop)
        ynames1 = kwargs.pop('ynames1',
                             flatten_list(self.subregions_w_prop(prop)))
        default_legends1 = [
            subregion.replace('.subregions', "")
            for subregion in flatten_list(self.rel_subregions)
        ]
        legends1 = kwargs.pop('legends1', default_legends1)

        # Create the plot.
        self.plotfig(title=title,
                     label=label,
                     ynames1=ynames1,
                     legends1=legends1,
                     **kwargs)
Beispiel #3
0
    def plot(self, ynames1=[], ylabel1=None, yunit1=None, legends1=[],
             leg1_kwargs={'loc': 'best'}, ax1=None,
             ynames2=[], ylabel2=None, yunit2=None, legends2=[],
             leg2_kwargs={'loc': 'best'}, ax2=None,
             xname='Time', xlabel=None, xunit=None,
             title=None, label="xy", incl_prefix=False, suffix=None,
             use_paren=True, **kwargs):
        r"""Plot data as points and/or curves in 2D Cartesian coordinates.

        A new figure is created if necessary.

        **Arguments:**

        - *ynames1*: Names of variables for the primary y axis

             If any names are invalid, then they will be skipped.

        - *ylabel1*: Label for the primary y axis

             If *ylabel1* is *None* (default) and all of the variables have the
             same Modelica_ description string, then the common description
             will be used.  Use '' for no label.

        - *yunit1*: String indicating the unit for the primary y-axis (see note
          for *xunit*)

             If *yunit1* is *None*, the Modelica_ *displayUnit* of the first
             entry of *ynames1* or the default unit (from *fcres.ini*) based on
             that variable's dimension will be used (in decreasing priority).

             .. Note:: Dimension checking is not currently performed, so it is
                important to ensure that a proper unit is chosen.

        - *legends1*: List of legend entries for variables assigned to the
          primary y axis

             If *legends1* is an empty list ([]), ynames1 will be used.  If
             *legends1* is *None* and all of the variables on the primary axis
             have the same unit, then no legend will be shown.

        - *leg1_kwargs*: Dictionary of keyword arguments for the primary legend

        - *ax1*: Primary y axes

             If *ax1* is not provided, then axes will be created in a new
             figure.

        - *ynames2*, *ylabel2*, *yunit2*, *legends2*, *leg2_kwargs*, and *ax2*:
          Similar to *ynames1*, *ylabel1*, *yunit1*, *legends1*, *leg1_kwargs*,
          and *ax1* but for the secondary y axis

        - *xname*: Name of the x-axis data

        - *xlabel*: Label for the x axis

             If *xlabel* is *None* (default), the variable's Modelica_
             description string will be applied.  Use '' for no label.

        - *xunit*: String indicating the unit for the x axis  (see note
          for *yunit1*)

             If *xunit* is *None*, the Modelica_ variable's *displayUnit* or
             the default unit (from *fcres.ini*) based on the variable's
             dimension will be used (in decreasing priority).

        - *title*: Title for the figure

             If *title* is *None* (default), then the title will be the base
             filename.  Use '' for no title.

        - *label*: Label for the figure (ignored if ax is provided)
             This will be used as a base filename if the figure is saved.

        - *incl_prefix*: If *True*, prefix the legend strings with the base
          filename of the class.

        - *suffix*: String that will be added at the end of the legend entries

        - *use_paren*: Add parentheses around the suffix

        - *\*\*kwargs*: Additional arguments for  :meth:`base.plot` (and thus to
          :meth:`matplotlib.pyplot.plot`)

             If both y axes are used (primary and secondary), then the *dashes*
             argument is ignored.  The curves on the primary axis will be solid
             and the curves on the secondary axis will be dotted.

        **Returns:**

        1. *ax1*: Primary y axes

        2. *ax2*: Secondary y axes

        **Example:**

        .. testsetup::
           >>> from fcres import closeall
           >>> closeall()

        .. code-block:: python

           >>> from fcres import SimRes, saveall

           >>> sim = SimRes('examples/SaturationPressure')
           >>> sim.plot(xname="subregion.gas.H2O.T",
           ...          ynames1=["subregion.gas.H2O.p", "p_sat"],
           ...          legends1=["FCSys (from Gibbs equilibrium)",
           ...                    "Modelica.Media (correlated function)"],
           ...          ylabel1='Saturation pressure',
           ...          title="Water Saturation Pressure",
           ...          label='examples/SaturationPressure') # doctest: +ELLIPSIS
           (<matplotlib.axes._subplots.AxesSubplot object at 0x...>, None)

           >>> saveall()
           Saved examples/SaturationPressure.pdf
           Saved examples/SaturationPressure.png

        .. only:: html

           .. image:: ../examples/SaturationPressure.png
              :scale: 70 %
              :alt: plot of water saturation pressure

        .. only:: latex

           .. figure:: ../examples/SaturationPressure.pdf
              :scale: 70 %

              Plot of water saturation pressure
        """
        # Note:  ynames1 is the first argument (besides self) so that plot()
        # can be called with simply a variable name.

        def _ystrings(ynames, ylabel, yunit, legends):
            """Generate a y-axis label and set of legend entries.
            """
            if ynames:
                if ylabel is None: # Try to create a suitable axis label.
                    descriptions = self.get_description(ynames)
                    # If the descriptions are the same, label the y axis with
                    # the 1st one.
                    ylabel = descriptions[0]
                    if len(set(descriptions)) <> 1:
                        print("The y-axis variable descriptions are not all "
                              "the same.  The first has been used.  Please "
                              "provide the proper name via ylabel1 or ylabel2.")
                if legends == []:
                    legends = ynames
                if incl_prefix:
                    legends = [self.fbase + ': ' + leg for leg in legends]
                if suffix:
                    legends = ([leg + ' (%s)' % suffix for leg in legends]
                               if use_paren else
                               [leg + suffix for leg in legends])
                assert len(set(self.get_dimension(ynames))) == 1, \
                    "The variables on the y-axis do not have the same physical dimension."
                if yunit is None:
                    # Use the unit of the 1st variable.
                    yunit = self.get_unit(ynames[0])
                if ylabel <> "":
                    ylabel = label_number(ylabel, yunit)

            return ylabel, yunit, legends

        # Process the inputs.
        ynames1 = base.flatten_list(ynames1)
        ynames2 = base.flatten_list(ynames2)
        assert ynames1 or ynames2, "No signals were provided."
        if title is None:
            title = self.fbase

        # Create primary and secondary axes if necessary.
        if not ax1:
            fig = base.figure(label)
            ax1 = fig.add_subplot(111)
        if ynames2 and not ax2:
            ax2 = ax1.twinx()

        # Generate the x-axis label.
        if xlabel is None:
            xlabel = 'Time' if xname == 'Time' else self.get_description(xname)
            # With Dymola 7.4, the description of the time variable will be
            # "Time in", which isn't good.
        if xunit is None:
            xunit = self.get_unit(xname)
        if xlabel<> "":
            xlabel = label_number(xlabel, xunit)

        # Generate the y-axis labels and sets of legend entries.
        ylabel1, yunit1, legends1 = _ystrings(ynames1, ylabel1, yunit1, legends1)
        ylabel2, yunit2, legends2 = _ystrings(ynames2, ylabel2, yunit2, legends2)

        # Read the data.
        if xname == 'Time':
            t_scale = lambda t: t*self._unitvalue('s')/self._unitvalue(xunit)
            y_1 = self.get_values(ynames1, f=self.to_unit(yunit1))
            y_2 = self.get_values(ynames2, f=self.to_unit(yunit2))
        else:
            x = self.get_values(xname, f=self.to_unit(xunit))
            times = self.get_times(xname)
            y_1 = self.get_values_at_times(ynames1, times, f=self.to_unit(yunit1))
            y_2 = self.get_values_at_times(ynames2, times, f=self.to_unit(yunit2))

        # Plot the data.
        if ynames1:
            if ynames2:
                # Use solid lines for primary axis and dotted lines for
                # secondary.
                kwargs['dashes'] = [(None, None)]
                base.plot(y_1, self.get_times(ynames1, f=t_scale) if xname == 'Time'
                          else x, ax1, label=legends1, **kwargs)
                kwargs['dashes'] = [(3, 3)]
                base.plot(y_2, self.get_times(ynames2, f=t_scale) if xname == 'Time'
                          else x, ax2, label=legends2, **kwargs)
            else:
                base.plot(y_1, self.get_times(ynames1, f=t_scale) if xname == 'Time'
                          else x, ax1, label=legends1, **kwargs)
        elif ynames2:
            base.plot(y_2, self.get_times(ynames2, f=t_scale) if xname == 'Time'
                      else x, ax2, label=legends2, **kwargs)

        # Decorate the figure.
        ax1.set_title(title)
        ax1.set_xlabel(xlabel)
        if ylabel1:
            ax1.set_ylabel(ylabel1)
        if ylabel2:
            ax2.set_ylabel(ylabel2)
        if legends1:
            if legends2:
                # Put the primary legend in the upper left and secondary in
                # upper right.
                leg1_kwargs['loc'] = 2
                leg2_kwargs['loc'] = 1
                ax1.legend(**leg1_kwargs)
                ax2.legend(**leg2_kwargs)
            else:
                ax1.legend(**leg1_kwargs)
        elif legends2:
            ax2.legend(**leg2_kwargs)

        return ax1, ax2
Beispiel #4
0
    def plot(self,
             ynames1=[],
             ylabel1=None,
             yunit1=None,
             legends1=[],
             leg1_kwargs={'loc': 'best'},
             ax1=None,
             ynames2=[],
             ylabel2=None,
             yunit2=None,
             legends2=[],
             leg2_kwargs={'loc': 'best'},
             ax2=None,
             xname='Time',
             xlabel=None,
             xunit=None,
             title=None,
             label="xy",
             incl_prefix=False,
             suffix=None,
             use_paren=True,
             **kwargs):
        r"""Plot data as points and/or curves in 2D Cartesian coordinates.

        A new figure is created if necessary.

        **Arguments:**

        - *ynames1*: Names of variables for the primary y axis

             If any names are invalid, then they will be skipped.

        - *ylabel1*: Label for the primary y axis

             If *ylabel1* is *None* (default) and all of the variables have the
             same Modelica_ description string, then the common description
             will be used.  Use '' for no label.

        - *yunit1*: String indicating the unit for the primary y-axis (see note
          for *xunit*)

             If *yunit1* is *None*, the Modelica_ *displayUnit* of the first
             entry of *ynames1* or the default unit (from *fcres.ini*) based on
             that variable's dimension will be used (in decreasing priority).

             .. Note:: Dimension checking is not currently performed, so it is
                important to ensure that a proper unit is chosen.

        - *legends1*: List of legend entries for variables assigned to the
          primary y axis

             If *legends1* is an empty list ([]), ynames1 will be used.  If
             *legends1* is *None* and all of the variables on the primary axis
             have the same unit, then no legend will be shown.

        - *leg1_kwargs*: Dictionary of keyword arguments for the primary legend

        - *ax1*: Primary y axes

             If *ax1* is not provided, then axes will be created in a new
             figure.

        - *ynames2*, *ylabel2*, *yunit2*, *legends2*, *leg2_kwargs*, and *ax2*:
          Similar to *ynames1*, *ylabel1*, *yunit1*, *legends1*, *leg1_kwargs*,
          and *ax1* but for the secondary y axis

        - *xname*: Name of the x-axis data

        - *xlabel*: Label for the x axis

             If *xlabel* is *None* (default), the variable's Modelica_
             description string will be applied.  Use '' for no label.

        - *xunit*: String indicating the unit for the x axis  (see note
          for *yunit1*)

             If *xunit* is *None*, the Modelica_ variable's *displayUnit* or
             the default unit (from *fcres.ini*) based on the variable's
             dimension will be used (in decreasing priority).

        - *title*: Title for the figure

             If *title* is *None* (default), then the title will be the base
             filename.  Use '' for no title.

        - *label*: Label for the figure (ignored if ax is provided)
             This will be used as a base filename if the figure is saved.

        - *incl_prefix*: If *True*, prefix the legend strings with the base
          filename of the class.

        - *suffix*: String that will be added at the end of the legend entries

        - *use_paren*: Add parentheses around the suffix

        - *\*\*kwargs*: Additional arguments for  :meth:`base.plot` (and thus to
          :meth:`matplotlib.pyplot.plot`)

             If both y axes are used (primary and secondary), then the *dashes*
             argument is ignored.  The curves on the primary axis will be solid
             and the curves on the secondary axis will be dotted.

        **Returns:**

        1. *ax1*: Primary y axes

        2. *ax2*: Secondary y axes

        **Example:**

        .. testsetup::
           >>> from fcres import closeall
           >>> closeall()

        .. code-block:: python

           >>> from fcres import SimRes, saveall

           >>> sim = SimRes('examples/SaturationPressure')
           >>> sim.plot(xname="subregion.gas.H2O.T",
           ...          ynames1=["subregion.gas.H2O.p", "p_sat"],
           ...          legends1=["FCSys (from Gibbs equilibrium)",
           ...                    "Modelica.Media (correlated function)"],
           ...          ylabel1='Saturation pressure',
           ...          title="Water Saturation Pressure",
           ...          label='examples/SaturationPressure') # doctest: +ELLIPSIS
           (<matplotlib.axes._subplots.AxesSubplot object at 0x...>, None)

           >>> saveall()
           Saved examples/SaturationPressure.pdf
           Saved examples/SaturationPressure.png

        .. only:: html

           .. image:: ../examples/SaturationPressure.png
              :scale: 70 %
              :alt: plot of water saturation pressure

        .. only:: latex

           .. figure:: ../examples/SaturationPressure.pdf
              :scale: 70 %

              Plot of water saturation pressure
        """

        # Note:  ynames1 is the first argument (besides self) so that plot()
        # can be called with simply a variable name.

        def _ystrings(ynames, ylabel, yunit, legends):
            """Generate a y-axis label and set of legend entries.
            """
            if ynames:
                if ylabel is None:  # Try to create a suitable axis label.
                    descriptions = self.get_description(ynames)
                    # If the descriptions are the same, label the y axis with
                    # the 1st one.
                    ylabel = descriptions[0]
                    if len(set(descriptions)) <> 1:
                        print(
                            "The y-axis variable descriptions are not all "
                            "the same.  The first has been used.  Please "
                            "provide the proper name via ylabel1 or ylabel2.")
                if legends == []:
                    legends = ynames
                if incl_prefix:
                    legends = [self.fbase + ': ' + leg for leg in legends]
                if suffix:
                    legends = ([leg + ' (%s)' % suffix
                                for leg in legends] if use_paren else
                               [leg + suffix for leg in legends])
                assert len(set(self.get_dimension(ynames))) == 1, \
                    "The variables on the y-axis do not have the same physical dimension."
                if yunit is None:
                    # Use the unit of the 1st variable.
                    yunit = self.get_unit(ynames[0])
                if ylabel <> "":
                    ylabel = label_number(ylabel, yunit)

            return ylabel, yunit, legends

        # Process the inputs.
        ynames1 = base.flatten_list(ynames1)
        ynames2 = base.flatten_list(ynames2)
        assert ynames1 or ynames2, "No signals were provided."
        if title is None:
            title = self.fbase

        # Create primary and secondary axes if necessary.
        if not ax1:
            fig = base.figure(label)
            ax1 = fig.add_subplot(111)
        if ynames2 and not ax2:
            ax2 = ax1.twinx()

        # Generate the x-axis label.
        if xlabel is None:
            xlabel = 'Time' if xname == 'Time' else self.get_description(xname)
            # With Dymola 7.4, the description of the time variable will be
            # "Time in", which isn't good.
        if xunit is None:
            xunit = self.get_unit(xname)
        if xlabel <> "":
            xlabel = label_number(xlabel, xunit)

        # Generate the y-axis labels and sets of legend entries.
        ylabel1, yunit1, legends1 = _ystrings(ynames1, ylabel1, yunit1,
                                              legends1)
        ylabel2, yunit2, legends2 = _ystrings(ynames2, ylabel2, yunit2,
                                              legends2)

        # Read the data.
        if xname == 'Time':
            t_scale = lambda t: t * self._unitvalue('s') / self._unitvalue(
                xunit)
            y_1 = self.get_values(ynames1, f=self.to_unit(yunit1))
            y_2 = self.get_values(ynames2, f=self.to_unit(yunit2))
        else:
            x = self.get_values(xname, f=self.to_unit(xunit))
            times = self.get_times(xname)
            y_1 = self.get_values_at_times(ynames1,
                                           times,
                                           f=self.to_unit(yunit1))
            y_2 = self.get_values_at_times(ynames2,
                                           times,
                                           f=self.to_unit(yunit2))

        # Plot the data.
        if ynames1:
            if ynames2:
                # Use solid lines for primary axis and dotted lines for
                # secondary.
                kwargs['dashes'] = [(None, None)]
                base.plot(y_1,
                          self.get_times(ynames1, f=t_scale)
                          if xname == 'Time' else x,
                          ax1,
                          label=legends1,
                          **kwargs)
                kwargs['dashes'] = [(3, 3)]
                base.plot(y_2,
                          self.get_times(ynames2, f=t_scale)
                          if xname == 'Time' else x,
                          ax2,
                          label=legends2,
                          **kwargs)
            else:
                base.plot(y_1,
                          self.get_times(ynames1, f=t_scale)
                          if xname == 'Time' else x,
                          ax1,
                          label=legends1,
                          **kwargs)
        elif ynames2:
            base.plot(
                y_2,
                self.get_times(ynames2, f=t_scale) if xname == 'Time' else x,
                ax2,
                label=legends2,
                **kwargs)

        # Decorate the figure.
        ax1.set_title(title)
        ax1.set_xlabel(xlabel)
        if ylabel1:
            ax1.set_ylabel(ylabel1)
        if ylabel2:
            ax2.set_ylabel(ylabel2)
        if legends1:
            if legends2:
                # Put the primary legend in the upper left and secondary in
                # upper right.
                leg1_kwargs['loc'] = 2
                leg2_kwargs['loc'] = 1
                ax1.legend(**leg1_kwargs)
                ax2.legend(**leg2_kwargs)
            else:
                ax1.legend(**leg1_kwargs)
        elif legends2:
            ax2.legend(**leg2_kwargs)

        return ax1, ax2