Repository: ross-rotordynamics/ross
Pull request #629 (2020-07-14 12:38:27)

General improvements in plot_random_var()
- Remove subplot titles. It was repetitive and oddly located.
- Add ross plotly theme.
- Legends are grouped to reduce graphical pollution.
- Change from_fluid_flow classmethod to calculate the bearing coefficients numerically.
- Change coefficients labels on plot_random_var. Names were too large on graphs.
- Change default option for plotting all the random variables.
- Update tests


Patch:
diff --git a/ross/stochastic/st_bearing_seal_element.py b/ross/stochastic/st_bearing_seal_element.py
index 88f50286..4f67c6b1 100644
--- a/ross/stochastic/st_bearing_seal_element.py
+++ b/ross/stochastic/st_bearing_seal_element.py
@@ -7,8 +7,8 @@ import numpy as np
 
 from ross.bearing_seal_element import BearingElement
 from ross.fluid_flow import fluid_flow as flow
-from ross.fluid_flow.fluid_flow_coefficients import (
-    calculate_short_damping_matrix, calculate_short_stiffness_matrix)
+from ross.fluid_flow.fluid_flow_coefficients import \
+    calculate_stiffness_and_damping_coefficients
 from ross.stochastic.st_results_elements import plot_histogram
 
 # fmt: on
@@ -297,7 +297,7 @@ class ST_BearingElement:
 
         return f_list
 
-    def plot_random_var(self, var_list=[], histogram_kwargs={}, plot_kwargs={}):
+    def plot_random_var(self, var_list=None, histogram_kwargs=None, plot_kwargs=None):
         """Plot histogram and the PDF.
 
         This function creates a histogram to display the random variable
@@ -307,6 +307,7 @@ class ST_BearingElement:
         ----------
         var_list : list, optional
             List of random variables, in string format, to plot.
+            Default is plotting all the random variables.
         histogram_kwargs : dict, optional
             Additional key word arguments can be passed to change
             the plotly.go.histogram (e.g. histnorm="probability density", nbinsx=20...).
@@ -329,24 +330,26 @@ class ST_BearingElement:
         >>> # fig.show()
         """
         label = dict(
-            kxx="Direct stiffness in the X direction",
-            kxy="Cross coupled stiffness in the X direction",
-            kyx="Cross coupled stiffness in the Y direction",
-            kyy="Direct stiffness in the Y direction",
-            cxx="Direct damping in the X direction",
-            cxy="Cross coupled damping in the X direction",
-            cyx="Cross coupled damping in the Y direction",
-            cyy="Direct damping in the y direction",
+            kxx="Kxx",
+            kxy="Kxy",
+            kyx="Kyx",
+            kyy="Kyy",
+            cxx="Cxx",
+            cxy="Cxy",
+            cyx="Cyx",
+            cyy="Cyy",
         )
-        if not all(var in self.is_random for var in var_list):
+        if var_list is None:
+            var_list = self.is_random
+        elif not all(var in self.is_random for var in var_list):
             raise ValueError(
-                "Not random variable in var_list. Select variables from {}".format(
+                "Random variable not in var_list. Select variables from {}".format(
                     self.is_random
                 )
             )
 
         return plot_histogram(
-            self.attribute_dict, label, var_list, histogram_kwargs={}, plot_kwargs={}
+            self.attribute_dict, label, var_list, histogram_kwargs, plot_kwargs
         )
 
     @classmethod
@@ -355,17 +358,19 @@ class ST_BearingElement:
         n,
         nz,
         ntheta,
-        nradius,
         length,
         omega,
         p_in,
         p_out,
         radius_rotor,
         radius_stator,
-        visc,
-        rho,
+        viscosity,
+        density,
+        attitude_angle=None,
         eccentricity=None,
         load=None,
+        omegap=None,
+        immediately_calculate_pressure_matrix_numerically=True,
         tag=None,
         n_link=None,
         scale_factor=1,
@@ -381,7 +386,8 @@ class ST_BearingElement:
             List of the object attributes to become random.
             Possibilities:
                 ["length", "omega", "p_in", "p_out", "radius_rotor",
-                 "radius_stator", "visc", "rho", "eccentricity", "load"]
+                 "radius_stator", "viscosity", "density", "attitude_angle",
+                 "eccentricity", "load", "omegap"]
         tag: str, optional
             A tag to name the element
             Default is None.
@@ -440,10 +446,10 @@ class ST_BearingElement:
         Fluid characteristics
         ^^^^^^^^^^^^^^^^^^^^^
         Describes the fluid characteristics.
-        visc: float, list
+        viscosity: float, list
             Viscosity (Pa.s).
             Input a list to make it random.
-        rho: float, list
+        density: float, list
             Fluid density(Kg/m^3).
             Input a list to make it random.
 
@@ -456,23 +462,23 @@ class ST_BearingElement:
         --------
         >>> import numpy as np
         >>> import ross.stochastic as srs
-        >>> nz = 30
-        >>> ntheta = 20
-        >>> nradius = 11
-        >>> length = 0.03
+        >>> nz = 8
+        >>> ntheta = 64
+        >>> length = 0.01
         >>> omega = 157.1
         >>> p_in = 0.
         >>> p_out = 0.
-        >>> radius_rotor = 0.0499
-        >>> radius_stator = 0.05
-        >>> eccentricity = (radius_stator - radius_rotor)*0.2663
-        >>> visc = np.random.uniform(0.1, 0.2, 5)
-        >>> rho = 860.0
-        >>> elms = srs.ST_BearingElement.from_fluid_flow(
-        ...     0, nz, ntheta, nradius, length,
+        >>> radius_rotor = 0.08
+        >>> radius_stator = 0.1
+        >>> viscosity = np.random.uniform(0.01, 0.02, 5)
+        >>> density = 860.
+        >>> eccentricity = 0.001
+        >>> attitude_angle = np.pi
+        >>> elms = ST_BearingElement.from_fluid_flow(
+        ...     0, nz, ntheta, length,
         ...     omega, p_in, p_out, radius_rotor,
-        ...     radius_stator, visc, rho,
-        ...     eccentricity=eccentricity, is_random=["visc"]
+        ...     radius_stator, viscosity, density, attitude_angle,
+        ...     eccentricity, is_random=["viscosity"]
         ... )
         >>> len(list(iter(elms)))
         5
@@ -500,20 +506,21 @@ class ST_BearingElement:
             fluid_flow = flow.FluidFlow(
                 attribute_dict["nz"][i],
                 attribute_dict["ntheta"][i],
-                attribute_dict["nradius"][i],
                 attribute_dict["length"][i],
                 attribute_dict["omega"][i],
                 attribute_dict["p_in"][i],
                 attribute_dict["p_out"][i],
                 attribute_dict["radius_rotor"][i],
                 attribute_dict["radius_stator"][i],
-                attribute_dict["visc"][i],
-                attribute_dict["rho"][i],
-                eccentricity=attribute_dict["eccentricity"][i],
-                load=attribute_dict["load"][i],
+                attribute_dict["viscosity"][i],
+                attribute_dict["density"][i],
+                attribute_dict["attitude_angle"][i],
+                attribute_dict["eccentricity"][i],
+                attribute_dict["load"][i],
+                attribute_dict["omegap"][i],
+                attribute_dict["immediately_calculate_pressure_matrix_numerically"][i],
             )
-            c = calculate_short_damping_matrix(fluid_flow)
-            k = calculate_short_stiffness_matrix(fluid_flow)
+            k, c = calculate_stiffness_and_damping_coefficients(fluid_flow)
             args_dict["kxx"].append(k[0])
             args_dict["kxy"].append(k[1])
             args_dict["kyx"].append(k[2])
diff --git a/ross/stochastic/st_disk_element.py b/ross/stochastic/st_disk_element.py
index 0c14a003..fa057d80 100644
--- a/ross/stochastic/st_disk_element.py
+++ b/ross/stochastic/st_disk_element.py
@@ -185,7 +185,7 @@ class ST_DiskElement:
 
         return f_list
 
-    def plot_random_var(self, var_list=[], histogram_kwargs={}, plot_kwargs={}):
+    def plot_random_var(self, var_list=None, histogram_kwargs=None, plot_kwargs=None):
         """Plot histogram and the PDF.
 
         This function creates a histogram to display the random variable
@@ -195,6 +195,7 @@ class ST_DiskElement:
         ----------
         var_list : list, optional
             List of random variables, in string format, to plot.
+            Default is plotting all the random variables.
         histogram_kwargs : dict, optional
             Additional key word arguments can be passed to change
             the plotly.go.histogram (e.g. histnorm="probability density", nbinsx=20...).
@@ -219,9 +220,11 @@ class ST_DiskElement:
         label = dict(
             m="Mass", Id="Diametral moment of inertia", Ip="Polar moment of inertia",
         )
-        if not all(var in self.is_random for var in var_list):
+        if var_list is None:
+            var_list = self.is_random
+        elif not all(var in self.is_random for var in var_list):
             raise ValueError(
-                "Not random variable in var_list. Select variables from {}".format(
+                "Random variable not in var_list. Select variables from {}".format(
                     self.is_random
                 )
             )
diff --git a/ross/stochastic/st_materials.py b/ross/stochastic/st_materials.py
index a7efd9c4..d0f95f2a 100644
--- a/ross/stochastic/st_materials.py
+++ b/ross/stochastic/st_materials.py
@@ -209,7 +209,7 @@ class ST_Material:
 
         return f_list
 
-    def plot_random_var(self, var_list=[], histogram_kwargs={}, plot_kwargs={}):
+    def plot_random_var(self, var_list=None, histogram_kwargs=None, plot_kwargs=None):
         """Plot histogram and the PDF.
 
         This function creates a histogram to display the random variable
@@ -219,6 +219,7 @@ class ST_Material:
         ----------
         var_list : list, optional
             List of random variables, in string format, to plot.
+            Default is plotting all the random variables.
         histogram_kwargs : dict, optional
             Additional key word arguments can be passed to change
             the plotly.go.histogram (e.g. histnorm="probability density", nbinsx=20...).
@@ -245,14 +246,15 @@ class ST_Material:
             E="Young's Modulus",
             G_s="Shear Modulus",
             Poisson="Poisson coefficient",
-            rho="density",
+            rho="Density",
         )
-        is_random = self.is_random
 
-        if not all(var in self.is_random for var in var_list):
+        if var_list is None:
+            var_list = self.is_random
+        elif not all(var in self.is_random for var in var_list):
             raise ValueError(
-                "Not random variable in var_list. Select variables from {}".format(
-                    is_random
+                "Random variable not in var_list. Select variables from {}".format(
+                    self.is_random
                 )
             )
 
diff --git a/ross/stochastic/st_point_mass.py b/ross/stochastic/st_point_mass.py
index 9ab31bc1..86205b0a 100644
--- a/ross/stochastic/st_point_mass.py
+++ b/ross/stochastic/st_point_mass.py
@@ -184,7 +184,7 @@ class ST_PointMass:
 
         return f_list
 
-    def plot_random_var(self, var_list=[], histogram_kwargs={}, plot_kwargs={}):
+    def plot_random_var(self, var_list=None, histogram_kwargs=None, plot_kwargs=None):
         """Plot histogram and the PDF.
 
         This function creates a histogram to display the random variable
@@ -194,6 +194,7 @@ class ST_PointMass:
         ----------
         var_list : list, optional
             List of random variables, in string format, to plot.
+            Default is plotting all the random variables.
         histogram_kwargs : dict, optional
             Additional key word arguments can be passed to change
             the plotly.go.histogram (e.g. histnorm="probability density", nbinsx=20...).
@@ -218,9 +219,11 @@ class ST_PointMass:
         label = dict(
             mx="Mass on the X direction", my="Mass on the Y direction", m="Mass",
         )
-        if not all(var in self.is_random for var in var_list):
+        if var_list is None:
+            var_list = self.is_random
+        elif not all(var in self.is_random for var in var_list):
             raise ValueError(
-                "Not random variable in var_list. Select variables from {}".format(
+                "Random variable not in var_list. Select variables from {}".format(
                     self.is_random
                 )
             )
diff --git a/ross/stochastic/st_results_elements.py b/ross/stochastic/st_results_elements.py
index 31eee27c..afecd8fd 100644
--- a/ross/stochastic/st_results_elements.py
+++ b/ross/stochastic/st_results_elements.py
@@ -2,17 +2,21 @@
 
 This modules provides functions to plot the elements statistic data.
 """
+from copy import copy
+
 import numpy as np
 from plotly import graph_objects as go
 from plotly import io as pio
 from plotly.subplots import make_subplots
 from scipy.stats import gaussian_kde
 
+from ross.plotly_theme import tableau_colors
+
 pio.renderers.default = "browser"
 
 
 def plot_histogram(
-    attribute_dict, label={}, var_list=[], histogram_kwargs={}, plot_kwargs={}
+    attribute_dict, label={}, var_list=[], histogram_kwargs=None, plot_kwargs=None
 ):
     """Plot histogram and the PDF.
 
@@ -41,27 +45,28 @@ def plot_histogram(
     subplots : Plotly graph_objects.make_subplots()
         A figure with the histogram plots.
     """
+    histogram_kwargs = {} if histogram_kwargs is None else copy(histogram_kwargs)
+    plot_kwargs = {} if plot_kwargs is None else copy(plot_kwargs)
+
     hist_default_values = dict(
         histnorm="probability density",
         cumulative_enabled=False,
         nbinsx=20,
-        marker_color="red",
+        marker_color=tableau_colors["red"],
         opacity=1.0,
     )
     for k, v in hist_default_values.items():
         histogram_kwargs.setdefault(k, v)
 
-    plot_default_values = dict(line=dict(width=4.0, color="royalblue"), opacity=1.0)
+    plot_default_values = dict(
+        line=dict(width=4.0, color=tableau_colors["blue"]), opacity=1.0
+    )
     for k, v in plot_default_values.items():
         plot_kwargs.setdefault(k, v)
 
     rows = 1 if len(var_list) < 2 else 2
     cols = len(var_list) // 2 + len(var_list) % 2
-    fig = make_subplots(
-        rows=rows,
-        cols=cols,
-        subplot_titles=["<b>Histogram - {}<b>".format(var) for var in var_list],
-    )
+    fig = make_subplots(rows=rows, cols=cols)
 
     for i, var in enumerate(var_list):
         row = i % 2 + 1
@@ -75,7 +80,13 @@ def plot_histogram(
             y_label = "Frequency"
 
         fig.add_trace(
-            go.Histogram(x=attribute_dict[var], name="Histogram", **histogram_kwargs),
+            go.Histogram(
+                x=attribute_dict[var],
+                name="Histogram",
+                legendgroup="Histogram",
+                showlegend=True if i == 0 else False,
+                **histogram_kwargs,
+            ),
             row=row,
             col=col,
         )
@@ -92,30 +103,22 @@ def plot_histogram(
                     y=kernel(x),
                     mode="lines",
                     name="PDF Estimation",
+                    legendgroup="PDF Estimation",
+                    showlegend=True if i == 0 else False,
                     **plot_kwargs,
                 ),
                 row=row,
                 col=col,
             )
         fig.update_xaxes(
-            title_text="{}".format(label[var]),
-            title_font=dict(family="Arial", size=20),
-            gridcolor="lightgray",
-            showline=True,
-            linewidth=2.5,
-            linecolor="black",
-            mirror=True,
+            title=dict(text="<b>{}</b>".format(label[var])),
+            exponentformat="E",
             row=row,
             col=col,
         )
         fig.update_yaxes(
-            title_text="{}".format(y_label),
-            title_font=dict(family="Arial", size=20),
-            gridcolor="lightgray",
-            showline=True,
-            linewidth=2.5,
-            linecolor="black",
-            mirror=True,
+            title=dict(text="<b>{}</b>".format(y_label), standoff=0),
+            exponentformat="E",
             row=row,
             col=col,
         )
diff --git a/ross/stochastic/st_shaft_element.py b/ross/stochastic/st_shaft_element.py
index 09d2d3d8..d735ddf5 100644
--- a/ross/stochastic/st_shaft_element.py
+++ b/ross/stochastic/st_shaft_element.py
@@ -260,7 +260,7 @@ class ST_ShaftElement:
 
         return f_list
 
-    def plot_random_var(self, var_list=[], histogram_kwargs={}, plot_kwargs={}):
+    def plot_random_var(self, var_list=None, histogram_kwargs=None, plot_kwargs=None):
         """Plot histogram and the PDF.
 
         This function creates a histogram to display the random variable
@@ -270,6 +270,7 @@ class ST_ShaftElement:
         ----------
         var_list : list, optional
             List of random variables, in string format, to plot.
+            Default is plotting all the random variables.
         histogram_kwargs : dict, optional
             Additional key word arguments can be passed to change
             the plotly.go.histogram (e.g. histnorm="probability density", nbinsx=20...).
@@ -302,9 +303,11 @@ class ST_ShaftElement:
         if "material" in is_random:
             is_random.remove("material")
 
-        if not all(var in self.is_random for var in var_list):
+        if var_list is None:
+            var_list = is_random
+        elif not all(var in is_random for var in var_list):
             raise ValueError(
-                "Not random variable in var_list. Select variables from {}".format(
+                "Random variable not in var_list. Select variables from {}".format(
                     is_random
                 )
             )


Test patch:
diff --git a/ross/tests/test_stochastic_elements.py b/ross/tests/test_stochastic_elements.py
index 373a52e8..c8e8df3d 100644
--- a/ross/tests/test_stochastic_elements.py
+++ b/ross/tests/test_stochastic_elements.py
@@ -188,7 +188,7 @@ def test_st_bearing_error_messages(rand_bearing_constant_coefs):
     with pytest.raises(ValueError) as ex:
         rand_bearing_constant_coefs.plot_random_var(["kxy"])
     assert (
-        "Not random variable in var_list. Select variables from ['kxx', 'cxx', 'kyy', 'cyy']"
+        "Random variable not in var_list. Select variables from ['kxx', 'cxx', 'kyy', 'cyy']"
         in str(ex.value)
     )
 
@@ -205,7 +205,7 @@ def test_st_disk_error_messages(rand_disk_from_inertia):
     with pytest.raises(ValueError) as ex:
         rand_disk_from_inertia.plot_random_var(["n"])
     assert (
-        "Not random variable in var_list. Select variables from ['m', 'Id', 'Ip']"
+        "Random variable not in var_list. Select variables from ['m', 'Id', 'Ip']"
         in str(ex.value)
     )
 
@@ -222,7 +222,7 @@ def test_st_shaft_error_messages(rand_shaft):
     with pytest.raises(ValueError) as ex:
         rand_shaft.plot_random_var(["n"])
     assert (
-        "Not random variable in var_list. Select variables from ['L', 'idl', 'odl', 'idr', 'odr']"
+        "Random variable not in var_list. Select variables from ['L', 'idl', 'odl', 'idr', 'odr']"
         in str(ex.value)
     )
 
@@ -238,7 +238,7 @@ def test_st_shaft_error_messages(rand_shaft):
 def test_st_point_mass_error_messages(rand_point_mass):
     with pytest.raises(ValueError) as ex:
         rand_point_mass.plot_random_var(["n"])
-    assert "Not random variable in var_list. Select variables from ['mx', 'my']" in str(
+    assert "Random variable not in var_list. Select variables from ['mx', 'my']" in str(
         ex.value
     )