From eff14f9f0fa8a22b769130dd853352f1448cb768 Mon Sep 17 00:00:00 2001 From: Francesco Witte Date: Sat, 21 Dec 2024 14:25:16 +0100 Subject: [PATCH] Allow non-latex style units and include posiblity to label every n-th line --- src/fluprodia/_utils.py | 2 +- src/fluprodia/fluid_property_diagram.py | 58 +++++++++++++++++-------- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/fluprodia/_utils.py b/src/fluprodia/_utils.py index 85adf07..d5882d6 100644 --- a/src/fluprodia/_utils.py +++ b/src/fluprodia/_utils.py @@ -259,7 +259,7 @@ def _beautiful_unit_string(unit): if '/' in unit: numerator = unit.split('/')[0] denominator = unit.split('/')[1] - unit = '$\\frac{' + numerator + '}{' + denominator + '}$' + unit = '$\\frac{\\text{' + numerator + '}}{\\text{' + denominator + '}}$' return unit diff --git a/src/fluprodia/fluid_property_diagram.py b/src/fluprodia/fluid_property_diagram.py index 9bb7cc8..6c2f299 100644 --- a/src/fluprodia/fluid_property_diagram.py +++ b/src/fluprodia/fluid_property_diagram.py @@ -500,7 +500,7 @@ def set_unit_system(self, **kwargs): ) raise ValueError(msg) - def _draw_isoline_label(self, fig, ax, isoline, property, idx, x, y, x_min, x_max, y_min, y_max): + def _draw_isoline_label(self, fig, ax, isoline, property, idx, x, y, x_min, x_max, y_min, y_max, latex_units): """Draw a label for an isoline. Parameters @@ -561,7 +561,10 @@ def _draw_isoline_label(self, fig, ax, isoline, property, idx, x, y, x_min, x_ma alpha = np.arctan(y_scaled / x_scaled) / (2 * np.pi) * 360 - unit = _beautiful_unit_string(self.units[property]) + if latex_units: + unit = _beautiful_unit_string(self.units[property]) + else: + unit = self.units[property] txt = f'{isoline} {unit}' text_bg_color = ax.get_facecolor() @@ -1104,8 +1107,8 @@ def _insert_Q_crossings(self, datapoints, property, data): return datapoints - def draw_isolines(self, fig, ax, diagram_type, x_min, x_max, y_min, y_max, isoline_data=None): - """_summary_ + def draw_isolines(self, fig, ax, diagram_type, x_min, x_max, y_min, y_max, isoline_data=None, latex_units=True): + """Draw the isolines onto an axes within a matplotlib figure Parameters ---------- @@ -1132,15 +1135,23 @@ def draw_isolines(self, fig, ax, diagram_type, x_min, x_max, y_min, y_max, isoli isoline_data : dict, optional Dictionary holding additional data on the isolines to be drawn, - by default None. These are + by default None. These are per isoline type + + - the isoline values with key :code:`values`, + - the isoline style with key :code:`style`, + - the number of labels per isoline :code:`labels_per_line` + (default: 1) and + - label every n-th line only :code:`label_every_nth` (default: 1) - - the isoline values with key :code:`values` and - - the isoline style with key :code:`style`. + following this structure: {"Q": {"values": np.array([0.0, 1.0])}} The islonline style is another dictionary holding keyword arguments of a :code:`matplotlib.lines.Line2D` object. See https://matplotlib.org/stable/api/_as_gen/matplotlib.lines.Line2D.html for more information. + + latex_units : bool, optional + Axis and isoline labels using LaTeX style units, by default True """ if isoline_data is None: isoline_data = {} @@ -1161,8 +1172,12 @@ def draw_isolines(self, fig, ax, diagram_type, x_min, x_max, y_min, y_max, isoli ax.set_xscale(x_scale) ax.set_yscale(y_scale) - x_label = f'{x_property} in {_beautiful_unit_string(self.units[x_property])}' - y_label = f'{y_property} in {_beautiful_unit_string(self.units[y_property])}' + if latex_units: + x_label = f'{x_property} in {_beautiful_unit_string(self.units[x_property])}' + y_label = f'{y_property} in {_beautiful_unit_string(self.units[y_property])}' + else: + x_label = f'{x_property} in {_beautiful_unit_string(self.units[x_property])}' + y_label = f'{y_property} in {_beautiful_unit_string(self.units[y_property])}' ax.set_xlabel(x_label) ax.set_ylabel(y_label) @@ -1177,6 +1192,8 @@ def draw_isolines(self, fig, ax, diagram_type, x_min, x_max, y_min, y_max, isoli data = getattr(self, property) isovalues = data['isolines'] + labels_per_line = 1 + label_every_nth = 1 if isoline in isoline_data.keys(): keys = isoline_data[isoline].keys() @@ -1193,7 +1210,13 @@ def draw_isolines(self, fig, ax, diagram_type, x_min, x_max, y_min, y_max, isoli isoline_data[isoline]['label_position'] ) - for isoval in isovalues.round(8): + if 'label_every_nth' in keys: + label_every_nth = isoline_data[isoline]['label_every_nth'] + + if 'labels_per_line' in keys: + labels_per_line = isoline_data[isoline]['labels_per_line'] + + for i, isoval in enumerate(isovalues.round(8)): if isoval not in data['isolines'].round(8): msg = ( f'Could not find data for {property} isoline with ' @@ -1227,14 +1250,15 @@ def draw_isolines(self, fig, ax, diagram_type, x_min, x_max, y_min, y_max, isoli ax.plot(x, y, **data['style']) - isoval = self.convert_from_SI(isoval, isoline) + if i % label_every_nth == 0: + isoval = self.convert_from_SI(isoval, isoline) - self._draw_isoline_label( - fig, ax, - isoval.round(8), isoline, - int(data['label_position'] * len(x)), - x, y, x_min, x_max, y_min, y_max - ) + self._draw_isoline_label( + fig, ax, + isoval.round(8), isoline, + int(data['label_position'] * len(x)), + x, y, x_min, x_max, y_min, y_max, latex_units + ) def _check_diagram_types(self, diagram_type): if not isinstance(diagram_type, str):