Ejemplo n.º 1
0
    def test_wet_bulb_temperature_empiric(self):
        """Empiric wet bulb temperature from dry bulb and relative humidity."""
        from psychrochart.equations import (
            wet_bulb_temperature_empiric, wet_bulb_temperature)
        from psychrochart.util import f_range

        for dry_temp_c in f_range(-20, 50, 2.5):
            for relative_humid in f_range(0.05, 1.0001, 0.05):
                wet_temp_c_ref = wet_bulb_temperature(
                    dry_temp_c, relative_humid)
                wet_temp_c = wet_bulb_temperature_empiric(
                    dry_temp_c, relative_humid)
                if -2.33 * dry_temp_c + 28.33 < relative_humid:
                    if abs(wet_temp_c - wet_temp_c_ref) > 1:
                        print('DT: {:.2f}, HR: {:.2f} => WT: [Aprox: {:.2f}, '
                              'Iter: {:.2f} -> ∆: {:.2f}]'.format(
                                dry_temp_c, relative_humid, wet_temp_c,
                                wet_temp_c_ref,
                                abs(wet_temp_c - wet_temp_c_ref)))
                    assert abs(wet_temp_c - wet_temp_c_ref) < 1.5
                else:
                    print('Difference between methods: {:.2f} vs ref={:.2f}'
                          .format(wet_temp_c, wet_temp_c_ref))
                    # out of range
                    assert abs(wet_temp_c - wet_temp_c_ref) > 0.
Ejemplo n.º 2
0
    def test_wet_bulb_temperature(self):
        """Wet bulb temperature from dry bulb temp and relative humidity."""
        from psychrochart.equations import (
            wet_bulb_temperature, relative_humidity_from_temps,
            PRESSURE_STD_ATM_KPA)
        from psychrochart.util import f_range

        precision = 0.00001
        p_atm = PRESSURE_STD_ATM_KPA

        for dry_temp_c in f_range(-10, 60, 2.5):
            for relative_humid in f_range(0.05, 1.0001, 0.05):
                wet_temp_c = wet_bulb_temperature(
                    dry_temp_c, relative_humid,
                    p_atm_kpa=p_atm, precision=precision)
                rh_calc = relative_humidity_from_temps(
                    dry_temp_c, wet_temp_c, p_atm_kpa=p_atm)
                # print('wet_temp_c(dbt, rh): {:.3f} ºC ({:.1f} ºC, {:.1f} %)'
                #       .format(wet_temp_c, dry_temp_c, relative_humid * 100))
                self.assertAlmostEqual(relative_humid, rh_calc, delta=0.01)

        precision = 0.00001
        p_atm = PRESSURE_STD_ATM_KPA * .75

        for dry_temp_c in f_range(-5, 50, 5):
            for relative_humid in f_range(0.05, 1.0001, 0.1):
                wet_temp_c = wet_bulb_temperature(
                    dry_temp_c, relative_humid,
                    p_atm_kpa=p_atm, precision=precision)
                rh_calc = relative_humidity_from_temps(
                    dry_temp_c, wet_temp_c, p_atm_kpa=p_atm)
                # print('wet_temp_c(dbt, rh): {:.3f} ºC ({:.1f} ºC, {:.1f} %)'
                #       .format(wet_temp_c, dry_temp_c, relative_humid * 100))
                self.assertAlmostEqual(relative_humid, rh_calc, delta=0.01)
Ejemplo n.º 3
0
def _gen_list_curves_range_temps(
        func_curve: Callable,
        dbt_min: float, dbt_max: float, increment: float,
        curves_values: list,
        p_atm_kpa: float=PRESSURE_STD_ATM_KPA) -> Tuple[List[float],
                                                        List[List[float]]]:
    """Generate a curve from a range of temperatures."""
    temps = f_range(dbt_min, dbt_max + increment, increment)
    curves = [func_curve(temps, value, p_atm_kpa) for value in curves_values]
    return temps, curves
Ejemplo n.º 4
0
    def test_plot_curve(self):
        """Test the plotting of PsychroCurve objects."""
        import matplotlib.pyplot as plt
        x_data = f_range(0, 50, 1)
        y_data = f_range(0, 50, 1)
        style = {"color": "k", "linewidth": 0.5, "linestyle": "-"}

        curve = PsychroCurve(x_data, y_data, style)

        # Plotting
        ax = plt.subplot()
        ax = curve.plot(ax)

        # Vertical line
        vertical_curve = PsychroCurve([25, 25], [2, 48])
        vertical_curve.plot(ax)

        # Add label
        vertical_curve.add_label(ax, 'TEST', va='baseline', ha='center')
Ejemplo n.º 5
0
    def test_curve(self):
        """Test the PsychroCurve object."""
        x_data = f_range(0, 50, 1)
        y_data = f_range(0, 50, 1)
        style = {"color": "k", "linewidth": 0.5, "linestyle": "-"}

        empty_curve = PsychroCurve()
        self.assertDictEqual(empty_curve.to_dict(), {})

        curve = PsychroCurve(x_data, y_data, style)

        # Dict export and import:
        d_curve = curve.to_dict()
        curve_d = PsychroCurve(**d_curve)

        self.assertCountEqual(curve.x_data, curve_d.x_data)
        self.assertListEqual(curve.x_data, curve_d.x_data)
        self.assertCountEqual(curve.y_data, curve_d.y_data)
        self.assertListEqual(curve.y_data, curve_d.y_data)
        self.assertDictEqual(curve.style, curve_d.style)
        self.assertDictEqual(d_curve, curve_d.to_dict())

        # JSON import export
        json_curve = curve.to_json()
        curve_js = PsychroCurve()
        self.assertEqual(str(curve_js), '<Empty PsychroCurve (label: None)>')
        if curve_js:  # Existence test
            raise AssertionError()
        curve_js = curve_js.from_json(json_curve)
        if not curve_js:  # Existence test
            raise AssertionError()
        self.assertEqual(str(curve_js),
                         '<PsychroCurve 50 values (label: None)>')

        self.assertCountEqual(curve.x_data, curve_js.x_data)
        self.assertListEqual(curve.x_data, curve_js.x_data)
        self.assertCountEqual(curve.y_data, curve_js.y_data)
        self.assertListEqual(curve.y_data, curve_js.y_data)
        self.assertDictEqual(curve.style, curve_js.style)
        self.assertDictEqual(json.loads(json_curve),
                             json.loads(curve_js.to_json()))
Ejemplo n.º 6
0
    def test_dew_point_temperature(self):
        """Dew point temperature testing."""
        from psychrochart.equations import (
            saturation_pressure_water_vapor, dew_point_temperature)
        from psychrochart.util import f_range

        temps = f_range(-20, 60, 1)
        for t in temps:
            p_sat = saturation_pressure_water_vapor(t)
            # w_sat = humidity_ratio(p_sat, p_atm_kpa=p_atm)
            temp_dp_sat = dew_point_temperature(p_sat)
            if temp_dp_sat < 0:
                self.assertAlmostEqual(temp_dp_sat, t, delta=3)
            else:
                self.assertAlmostEqual(temp_dp_sat, t, delta=2.5)
Ejemplo n.º 7
0
def _make_zone_dbt_rh(
        t_min: float, t_max: float, increment: float,
        rh_min: float, rh_max: float,
        p_atm_kpa: float=PRESSURE_STD_ATM_KPA,
        style: dict=None,
        label: str=None,
        logger=None) -> PsychroCurve:
    """Generate points for zone between constant dry bulb temps and RH."""
    temps = f_range(t_min, t_max + increment, increment)
    curve_rh_up = curve_constant_humidity_ratio(temps, rh_max, p_atm_kpa)
    curve_rh_down = curve_constant_humidity_ratio(temps, rh_min, p_atm_kpa)
    abs_humid = (curve_rh_up + curve_rh_down[::-1]
                 + [curve_rh_up[0]])  # type: List[float]
    temps_zone = temps + temps[::-1] + [temps[0]]  # type: List[float]
    return PsychroCurve(temps_zone, abs_humid, style,
                        type_curve='constant_rh_data', label=label,
                        logger=logger)
Ejemplo n.º 8
0
    def plot(self, ax: Axes=None) -> Axes:
        """Plot the psychrochart and return the matplotlib Axes instance."""
        def _apply_spines_style(axes, style, location='right'):
            for key in style:
                if (key == 'color') or (key == 'c'):
                    axes.spines[location].set_color(style[key])
                elif (key == 'linewidth') or (key == 'lw'):
                    axes.spines[location].set_linewidth(style[key])
                elif (key == 'linestyle') or (key == 'ls'):
                    axes.spines[location].set_linestyle(style[key])
                else:  # pragma: no cover
                    try:
                        getattr(axes.spines[location],
                                'set_{}'.format(key))(style[key])
                    except Exception as exc:
                        self._print_err(
                            "Error trying to apply spines attrs: %s. (%s)",
                            exc, dir(axes.spines[location]))

        # Prepare fig & axis
        fig_params = self.figure_params.copy()
        figsize = fig_params.pop('figsize', (16, 9))
        position = fig_params.pop('position', [0.025, 0.075, 0.925, 0.875])
        fontsize = fig_params.pop('fontsize', 10)
        x_style = fig_params.pop('x_axis', {})
        x_style_labels = fig_params.pop('x_axis_labels', {})
        x_style_ticks = fig_params.pop('x_axis_ticks', {})
        y_style = fig_params.pop('y_axis', {})
        y_style_labels = fig_params.pop('y_axis_labels', {})
        y_style_ticks = fig_params.pop('y_axis_ticks', {})
        partial_axis = fig_params.pop('partial_axis', True)

        # Create figure and format axis
        self._fig = figure.Figure(figsize=figsize, dpi=150, frameon=False)
        self._canvas = FigureCanvas(self._fig)
        if ax is None:
            ax = self._fig.gca(position=position)
        ax.yaxis.tick_right()
        ax.yaxis.set_label_position("right")
        ax.set_xlim(self.dbt_min, self.dbt_max)
        ax.set_ylim(self.w_min, self.w_max)
        ax.grid(False, which='major', axis='both')
        ax.grid(False, which='minor', axis='both')

        # Apply axis styles
        if fig_params['x_label'] is not None:
            style_axis = x_style_labels.copy()
            style_axis['fontsize'] *= 1.2
            ax.set_xlabel(fig_params['x_label'], **style_axis)
        if fig_params['y_label'] is not None:
            style_axis = y_style_labels.copy()
            style_axis['fontsize'] *= 1.2
            ax.set_ylabel(fig_params['y_label'], **style_axis)
        if fig_params['title'] is not None:
            ax.set_title(fig_params['title'],
                         fontsize=fontsize * 1.5, fontweight='bold')

        _apply_spines_style(ax, y_style, location='right')
        _apply_spines_style(ax, x_style, location='bottom')
        if partial_axis:  # Hide left and top axis
            ax.spines['left'].set_visible(False)
            ax.spines['top'].set_visible(False)
        else:
            _apply_spines_style(ax, y_style, location='left')
            _apply_spines_style(ax, x_style, location='top')

        if x_style_ticks:
            ax.tick_params(axis='x', **x_style_ticks)
        if y_style_ticks:
            ax.tick_params(axis='y', **y_style_ticks)

        if self.chart_params.get("with_constant_dry_temp", True):
            step_label = self.chart_params.get(
                "constant_temp_label_step", None)
            if step_label:  # Explicit xticks
                ticks = f_range(self.dbt_min, self.dbt_max + step_label / 10,
                                step_label)
                if not self.chart_params.get(
                        "constant_temp_label_include_limits", True):
                    ticks = [t for t in ticks
                             if t not in [self.dbt_min, self.dbt_max]]
                ax.set_xticks(ticks)
                ax.set_xticklabels(
                    ['{:g}'.format(t) for t in ticks], **x_style_labels)
        else:
            ax.set_xticks([])

        if self.chart_params.get("with_constant_humidity", True):
            step_label = self.chart_params.get(
                "constant_humid_label_step", None)
            if step_label:  # Explicit xticks
                ticks = f_range(self.w_min, self.w_max + step_label / 10,
                                step_label)
                if not self.chart_params.get(
                        "constant_humid_label_include_limits", True):
                    ticks = [t for t in ticks
                             if t not in [self.w_min, self.w_max]]
                ax.set_yticks(ticks)
                ax.set_yticklabels(
                    ['{:g}'.format(t) for t in ticks], **y_style_labels)
        else:
            ax.set_yticks([])

        # Plot curves:
        [getattr(self, curve_family).plot(ax)
         for curve_family in PSYCHRO_CURVES_KEYS
         if getattr(self, curve_family) is not None]

        # Plot zones:
        [zone.plot(ax=ax) for zone in self.zones]

        # Set the Axes object
        self._axes = ax
        return ax
Ejemplo n.º 9
0
    def _make_chart_data(self,
                         styles: Union[dict, str]=None,
                         zones_file: Union[dict, str]=None) -> None:
        """Generate the data to plot the psychrometric chart."""
        # Get styling
        config = load_config(styles)
        self.d_config = config
        self.temp_step = config['limits']['step_temp']

        self.figure_params = config['figure']
        self.dbt_min, self.dbt_max = config['limits']['range_temp_c']
        self.w_min, self.w_max = config['limits']['range_humidity_g_kg']
        self.chart_params = config['chart_params']

        # Base pressure
        if config['limits'].get('pressure_kpa') is not None:
            self.p_atm_kpa = config['limits']['pressure_kpa']
        elif config['limits'].get('altitude_m') is not None:
            self.altitude_m = config['limits']['altitude_m']
            self.p_atm_kpa = pressure_by_altitude(self.altitude_m)

        # Dry bulb constant lines (vertical):
        if self.chart_params["with_constant_dry_temp"]:
            step = self.chart_params["constant_temp_step"]
            style = config['constant_dry_temp']
            temps_vl = f_range(self.dbt_min, self.dbt_max, step)
            heights = [1000 * humidity_ratio(
                saturation_pressure_water_vapor(t),
                p_atm_kpa=self.p_atm_kpa) for t in temps_vl]

            self.constant_dry_temp_data = PsychroCurves(
                [PsychroCurve([t, t], [self.w_min, h], style,
                              type_curve='constant_dry_temp_data',
                              label=None, logger=self._logger)
                 for t, h in zip(temps_vl, heights)],
                family_label=self.chart_params["constant_temp_label"])

        # Absolute humidity constant lines (horizontal):
        if self.chart_params["with_constant_humidity"]:
            step = self.chart_params["constant_humid_step"]
            style = config['constant_humidity']
            ws_hl = f_range(self.w_min + step, self.w_max + step / 10, step)
            dew_points = solve_curves_with_iteration(
                'DEW POINT', [x / 1000 for x in ws_hl],
                lambda x: dew_point_temperature(
                        water_vapor_pressure(
                            x, p_atm_kpa=self.p_atm_kpa)),
                lambda x: humidity_ratio(
                    saturation_pressure_water_vapor(x),
                    p_atm_kpa=self.p_atm_kpa))

            self.constant_humidity_data = PsychroCurves(
                [PsychroCurve([t_dp, self.dbt_max], [w, w], style,
                              type_curve='constant_humidity_data',
                              label=None, logger=self._logger)
                 for w, t_dp in zip(ws_hl, dew_points)],
                family_label=self.chart_params["constant_humid_label"])

        # Constant relative humidity curves:
        if self.chart_params["with_constant_rh"]:
            rh_perc_values = self.chart_params["constant_rh_curves"]
            rh_label_values = self.chart_params.get("constant_rh_labels", [])
            label_loc = self.chart_params.get("constant_rh_labels_loc", .85)
            style = config["constant_rh"]
            temps_ct_rh, curves_ct_rh = _gen_list_curves_range_temps(
                curve_constant_humidity_ratio,
                self.dbt_min, self.dbt_max, self.temp_step,
                rh_perc_values, p_atm_kpa=self.p_atm_kpa)

            self.constant_rh_data = PsychroCurves(
                [PsychroCurve(
                    temps_ct_rh, curve_ct_rh, style,
                    type_curve='constant_rh_data',
                    label_loc=label_loc, label='RH {:g} %'.format(rh)
                    if round(rh, 1) in rh_label_values else None,
                    logger=self._logger)
                    for rh, curve_ct_rh in zip(rh_perc_values, curves_ct_rh)],
                family_label=self.chart_params["constant_rh_label"])

        # Constant enthalpy lines:
        if self.chart_params["with_constant_h"]:
            step = self.chart_params["constant_h_step"]
            start, end = self.chart_params["range_h"]
            enthalpy_values = f_range(start, end, step)
            h_label_values = self.chart_params.get("constant_h_labels", [])
            label_loc = self.chart_params.get("constant_h_labels_loc", 1.)
            style = config["constant_h"]
            temps_max_constant_h = [
                dry_temperature_for_enthalpy_of_moist_air(
                    self.w_min / 1000, h)
                for h in enthalpy_values]

            sat_points = solve_curves_with_iteration(
                'ENTHALPHY', enthalpy_values,
                lambda x: dry_temperature_for_enthalpy_of_moist_air(
                    self.w_min / 1000 + 0.1, x),
                lambda x: enthalpy_moist_air(
                    x, saturation_pressure_water_vapor(x),
                    p_atm_kpa=self.p_atm_kpa))

            self.constant_h_data = PsychroCurves(
                [PsychroCurve(
                    [t_sat, t_max], [1000 * humidity_ratio(
                        saturation_pressure_water_vapor(t_sat),
                        self.p_atm_kpa), self.w_min], style,
                    type_curve='constant_h_data',
                    label_loc=label_loc, label='{:g} kJ/kg_da'.format(h)
                    if round(h, 3) in h_label_values else None,
                    logger=self._logger)
                    for t_sat, t_max, h in zip(
                    sat_points, temps_max_constant_h, enthalpy_values)],
                family_label=self.chart_params["constant_h_label"])

        # Constant specific volume lines:
        if self.chart_params["with_constant_v"]:
            step = self.chart_params["constant_v_step"]
            start, end = self.chart_params["range_vol_m3_kg"]
            vol_values = f_range(start, end, step)
            vol_label_values = self.chart_params.get("constant_v_labels", [])
            label_loc = self.chart_params.get("constant_v_labels_loc", 1.)
            style = config["constant_v"]
            temps_max_constant_v = [
                dry_temperature_for_specific_volume_of_moist_air(
                    0, specific_vol, p_atm_kpa=self.p_atm_kpa)
                for specific_vol in vol_values]
            sat_points = solve_curves_with_iteration(
                'CONSTANT VOLUME', vol_values,
                lambda x: dry_temperature_for_specific_volume_of_moist_air(
                    0, x, p_atm_kpa=self.p_atm_kpa),
                lambda x: specific_volume(
                    x, saturation_pressure_water_vapor(x),
                    p_atm_kpa=self.p_atm_kpa))

            self.constant_v_data = PsychroCurves(
                [PsychroCurve(
                    [t_sat, t_max], [1000 * humidity_ratio(
                        saturation_pressure_water_vapor(t_sat),
                        self.p_atm_kpa), 0],
                    style, type_curve='constant_v_data',
                    label_loc=label_loc, label='{:g} m3/kg_da'.format(vol)
                    if round(vol, 3) in vol_label_values else None,
                    logger=self._logger)
                    for t_sat, t_max, vol in zip(
                    sat_points, temps_max_constant_v, vol_values)],
                family_label=self.chart_params["constant_v_label"])

        # Constant wet bulb temperature lines:
        if self.chart_params["with_constant_wet_temp"]:
            step = self.chart_params["constant_wet_temp_step"]
            start, end = self.chart_params["range_wet_temp"]
            wbt_values = f_range(start, end, step)
            wbt_label_values = self.chart_params.get(
                "constant_wet_temp_labels", [])
            label_loc = self.chart_params.get(
                "constant_wet_temp_labels_loc", .05)
            style = config["constant_wet_temp"]
            w_max_constant_wbt = [humidity_ratio(
                saturation_pressure_water_vapor(wbt), self.p_atm_kpa)
                for wbt in wbt_values]

            self.constant_wbt_data = PsychroCurves(
                [PsychroCurve(
                    [wbt, self.dbt_max],
                    [1000 * w_max,
                     1000 * humidity_ratio(
                         saturation_pressure_water_vapor(self.dbt_max)
                         * relative_humidity_from_temps(
                             self.dbt_max, wbt, p_atm_kpa=self.p_atm_kpa),
                         p_atm_kpa=self.p_atm_kpa)], style,
                    type_curve='constant_wbt_data',
                    label_loc=label_loc, label='{:g} °C'.format(wbt)
                    if wbt in wbt_label_values else None, logger=self._logger)
                    for wbt, w_max in zip(wbt_values, w_max_constant_wbt)],
                family_label=self.chart_params["constant_wet_temp_label"])

        # Saturation line:
        if True:
            sat_style = config["saturation"]
            temps_sat_line, w_sat_line = _gen_list_curves_range_temps(
                curve_constant_humidity_ratio,
                self.dbt_min, self.dbt_max, self.temp_step, [100],
                p_atm_kpa=self.p_atm_kpa)

            self.saturation = PsychroCurves(
                [PsychroCurve(
                    temps_sat_line, w_sat_line[0], sat_style,
                    type_curve='saturation', logger=self._logger)])

        # Zones
        if self.chart_params["with_zones"] or zones_file is not None:
            self.append_zones(zones_file)
Ejemplo n.º 10
0
    def test_custom_style_psychrochart_2(self):
        """Test the plot custom styling with dicts."""
        import logging
        from psychrochart.util import f_range

        custom_style = {
            'chart_params': {
                'constant_h_label': None,
                'constant_h_labels': [30, 40, 50, 60, 70, 80],
                'constant_h_step': 5,
                'constant_humid_label': None,
                'constant_humid_label_include_limits': False,
                'constant_humid_label_step': 5,
                'constant_humid_step': 2.5,
                'constant_rh_curves': [20, 40, 50, 60, 80],
                'constant_rh_label': None,
                'constant_rh_labels': [20, 30, 40, 50, 60],
                'constant_rh_labels_loc': 0.5,
                'constant_temp_label': None,
                'constant_temp_label_include_limits': False,
                'constant_temp_label_step': 10,
                'constant_temp_step': 5,
                'constant_v_label': None,
                'constant_v_labels': [0.83, 0.84, 0.85, 0.86, 0.87, 0.88],
                'constant_v_labels_loc': 0.1,
                'constant_v_step': 0.01,
                'constant_wet_temp_label': None,
                'constant_wet_temp_labels': [10, 15, 20, 25],
                'constant_wet_temp_step': 5,
                'range_wet_temp': [10, 30],
                'range_h': [10, 100],
                'range_vol_m3_kg': [0.82, 0.9],
                'with_constant_dry_temp': True,
                'with_constant_h': True,
                'with_constant_humidity': True,
                'with_constant_rh': True,
                'with_constant_v': True,
                'with_constant_wet_temp': True,
                'with_zones': False
            },
            'constant_dry_temp': {
                'color': [0.855, 0.145, 0.114, 0.7],
                'linestyle': ':',
                'linewidth': 0.75
            },
            'constant_h': {
                'color': [0.251, 0.0, 0.502, 0.7],
                'linestyle': '-',
                'linewidth': 2
            },
            'constant_humidity': {
                'color': [0.0, 0.125, 0.376, 0.7],
                'linestyle': ':',
                'linewidth': 0.75
            },
            'constant_rh': {
                'color': [0.0, 0.498, 1.0, 0.7],
                'linestyle': '-.',
                'linewidth': 2
            },
            'constant_v': {
                'color': [0.0, 0.502, 0.337, 0.7],
                'linestyle': '-',
                'linewidth': 1
            },
            'constant_wet_temp': {
                'color': [0.498, 0.875, 1.0, 0.7],
                'linestyle': '-',
                'linewidth': 1
            },
            'figure': {
                'figsize': [16, 9],
                'partial_axis': True,
                'position': [0, 0, 1, 1],
                'title': None,
                'x_axis': {
                    'color': [0.855, 0.145, 0.114],
                    'linestyle': '-',
                    'linewidth': 2
                },
                'x_axis_labels': {
                    'color': [0.855, 0.145, 0.114],
                    'fontsize': 10
                },
                'x_axis_ticks': {
                    'color': [0.855, 0.145, 0.114],
                    'direction': 'in',
                    'pad': -20
                },
                'x_label': None,
                'y_axis': {
                    'color': [0.0, 0.125, 0.376],
                    'linestyle': '-',
                    'linewidth': 2
                },
                'y_axis_labels': {
                    'color': [0.0, 0.125, 0.376],
                    'fontsize': 10
                },
                'y_axis_ticks': {
                    'color': [0.0, 0.125, 0.376],
                    'direction': 'in',
                    'pad': -20
                },
                'y_label': None
            },
            # 'limits': {'range_humidity_g_kg': [2.5, 17.5],
            'limits': {
                'range_humidity_g_kg': [2.5, 20],
                'range_temp_c': [15, 35],
                'step_temp': 0.5,
                'pressure_kpa': 101.42
            },
            'saturation': {
                'color': [0.855, 0.145, 0.114],
                'linestyle': '-',
                'linewidth': 5
            },
            'zones': [{
                'label': 'Summer',
                'points_x': [23, 28],
                'points_y': [40, 60],
                'style': {
                    'edgecolor': [1.0, 0.749, 0.0, 0.8],
                    'facecolor': [1.0, 0.749, 0.0, 0.2],
                    'linestyle': '--',
                    'linewidth': 2
                },
                'zone_type': 'dbt-rh'
            }, {
                'label': 'Winter',
                'points_x': [18, 23],
                'points_y': [35, 55],
                'style': {
                    'edgecolor': [0.498, 0.624, 0.8],
                    'facecolor': [0.498, 0.624, 1.0, 0.2],
                    'linestyle': '--',
                    'linewidth': 2
                },
                'zone_type': 'dbt-rh'
            }]
        }
        chart = PsychroChart(custom_style, logger=logging, verbose=True)
        chart.plot()
        chart.plot_legend()

        path_png = os.path.join(basedir, 'test_custom_psychrochart_2.png')
        chart.save(path_png, transparent=True)
        chart.close_fig()

        for p in f_range(90., 105., 1.):
            print('Trying with P: {} kPa:'.format(p))
            custom_style['limits']['pressure_kpa'] = p
            PsychroChart(custom_style, logger=logging, verbose=True)