def add_label(self, ax: Axes=None, text_label: Optional[str]=None, va: Optional[str]=None, ha: Optional[str]=None, loc: float=None, **params) -> Axes: """Annotate the curve with its label.""" num_samples = len(self.x_data) assert num_samples > 1 text_style = {'va': 'bottom', 'ha': 'left', 'color': [0., 0., 0.]} loc_f = self._label_loc if loc is None else loc # type: float label = self._label if text_label is None else text_label # type: str def _tilt_params(x_data, y_data, idx_0, idx_f): delta_x = x_data[idx_f] - self.x_data[idx_0] delta_y = y_data[idx_f] - self.y_data[idx_0] rotation_deg = degrees(atan2(delta_y, delta_x)) if delta_x == 0: tilt_curve = 1e12 else: tilt_curve = delta_y / delta_x return rotation_deg, tilt_curve if num_samples == 2: xmin, xmax = ax.get_xlim() rotation, tilt = _tilt_params(self.x_data, self.y_data, 0, 1) if abs(rotation) == 90: text_x = self.x_data[0] text_y = (self.y_data[0] + loc_f * (self.y_data[1] - self.y_data[0])) elif loc_f == 1.: if self.x_data[1] > xmax: text_x = xmax text_y = self.y_data[0] + tilt * (xmax - self.x_data[0]) else: text_x, text_y = self.x_data[1], self.y_data[1] label += ' ' text_style['ha'] = 'right' else: text_x = self.x_data[0] + loc_f * (xmax - xmin) if text_x < xmin: text_x = xmin + loc_f * (xmax - xmin) text_y = self.y_data[0] + tilt * (text_x - self.x_data[0]) else: idx = min(num_samples - 2, int(num_samples * loc_f)) rotation, tilt = _tilt_params(self.x_data, self.y_data, idx, idx + 1) text_x, text_y = self.x_data[idx], self.y_data[idx] text_style['ha'] = 'center' if 'color' in self.style: text_style['color'] = mod_color(self.style['color'], -25) if ha is not None: text_style['ha'] = ha if va is not None: text_style['va'] = va if params: text_style.update(params) self._annotate_label(ax, label, text_x, text_y, rotation, text_style) return ax
def plot_arrows_dbt_rh(self, points_pairs: Dict) -> Dict: """Append individual points to the plot.""" points_plot = {} default_style = { "linewidth": 0, "color": [1, .8, 0.1, .8], "arrowstyle": 'wedge'} for key, pair_point in points_pairs.items(): plot_params = default_style.copy() if isinstance(pair_point, dict): if 'style' in pair_point and "color" in pair_point['style']: plot_params['color'] = mod_color( pair_point['style']['color'], .6) # set alpha point1, point2 = pair_point['xy'] else: point1, point2 = pair_point temp1 = point1[0] temp2 = point2[0] w_g_ka1 = curve_constant_humidity_ratio( [temp1], rh_percentage=point1[1], p_atm_kpa=self.p_atm_kpa)[0] w_g_ka2 = curve_constant_humidity_ratio( [temp2], rh_percentage=point2[1], p_atm_kpa=self.p_atm_kpa)[0] self._handlers_annotations.append( self.axes.annotate( '', (temp2, w_g_ka2), xytext=(temp1, w_g_ka1), arrowprops=plot_params)) points_plot[key] = (temp1, w_g_ka1), (temp2, w_g_ka2), plot_params return points_plot
def test_color_palette(self): """Test rgba utilities.""" from psychrochart.util import mod_color def _to_8bit_color(color): return tuple( int(round(255 * c)) if i < 3 else c for i, c in enumerate(color)) color_base = [0.475, 0.612, 0.075] self.assertEqual(_to_8bit_color(color_base), (121, 156, 19)) color_light_20 = mod_color(color_base, 20) self.assertEqual(_to_8bit_color(color_light_20), (145, 187, 23)) color_dark_40 = mod_color(color_base, -40) self.assertEqual(_to_8bit_color(color_dark_40), (73, 94, 11)) color_alpha_08 = mod_color(color_base, 0.8) self.assertEqual(_to_8bit_color(color_alpha_08), (121, 156, 19, 0.8))
def plot(self, ax: Axes) -> Axes: """Plot the curve.""" xmin, xmax = ax.get_xlim() ymin, ymax = ax.get_ylim() if not self.x_data or not self.y_data or not _between_limits( self.x_data, self.y_data, xmin, xmax, ymin, ymax): self._print_err( '{} (label:{}) Not between limits ([{}, {}, {}, {}]) ' '-> x:{}, y:{}'.format(self._type_curve, self._label, xmin, xmax, ymin, ymax, self.x_data, self.y_data)) return ax if self._is_patch and self.y_data is not None: assert len(self.y_data) > 2 verts = list(zip(self.x_data, self.y_data)) codes = ([Path.MOVETO] + [Path.LINETO] * (len(self.y_data) - 2) + [Path.CLOSEPOLY]) path = Path(verts, codes) patch = patches.PathPatch(path, **self.style) ax.add_patch(patch) if self._label is not None: bbox_p = path.get_extents() text_x = .5 * (bbox_p.x0 + bbox_p.x1) text_y = .5 * (bbox_p.y0 + bbox_p.y1) style = { 'ha': 'center', 'va': 'center', "backgroundcolor": [1, 1, 1, .4] } if 'edgecolor' in self.style: style['color'] = mod_color(self.style['edgecolor'], -25) self._annotate_label(ax, self._label, text_x, text_y, 0, style) else: ax.plot(self.x_data, self.y_data, **self.style) if self._label is not None: self.add_label(ax) return ax