Source code for pysmithchart.polar_transform
"""This module contains the implementation for polar transform."""
from collections.abc import Iterable
from matplotlib.transforms import Transform
import numpy as np
__all__ = ["PolarTranslate", "PolarTranslateInverse"]
class BasePolarTransform(Transform):
"""Abstract class to work around circular imports.
Attributes:
axes (SmithAxes): The parent `SmithAxes` instance.
pad (float): The radial distance to translate points inward toward the center.
font_size (float): The font size used to calculate additional y-axis translation.
"""
#: The number of input dimensions (always 2).
input_dims = 2
#: The number of output dimensions (always 2).
output_dims = 2
#: Whether the transform is separable (always False).
is_separable = False
def __init__(self, axes, pad, font_size, *args, **kwargs):
"""Initialize the inverse polar translation transformation."""
super().__init__(*args, **kwargs)
self.axes = axes
self.pad = pad
self.font_size = font_size
def inverted(self):
"""To be implemented in subclasses."""
raise NotImplementedError("Subclasses must implement this method.")
[docs]
class PolarTranslateInverse(BasePolarTransform):
"""
Inverse transformation for `PolarTranslate`.
This class reverses the effect of the radial translation applied by `PolarTranslate`.
"""
[docs]
def transform_non_affine(self, values):
"""
Apply the non-affine inverse polar translation transformation.
Args:
values (array-like):
A single point (x, y) or a list of points to transform.
Returns:
list or tuple:
The transformed points, translated inward toward the center.
"""
def _inverse_translate(_xy):
x, y = _xy
ang = np.angle(complex(x - x0, y - y0))
return (
x - np.cos(ang) * self.pad,
y - np.sin(ang) * (self.pad + 0.5 * self.font_size),
)
x0, y0 = self.axes.transAxes.transform([0.5, 0.5])
if isinstance(values[0], Iterable):
return list(map(_inverse_translate, values))
return _inverse_translate(values)
[docs]
def inverted(self):
"""
Return the forward transformation (`PolarTranslate`).
Returns:
PolarTranslate:
The forward transformation.
"""
return PolarTranslate(self.axes, self.pad, self.font_size)
[docs]
class PolarTranslate(BasePolarTransform):
"""
Transformation for translating points radially outward from the center of the Smith chart.
This transformation moves points away from the center of the Smith chart (typically at [0.5, 0.5]
in axis coordinates) by a specified padding distance. The y-coordinate translation includes an
additional adjustment based on the font size.
"""
[docs]
def transform_non_affine(self, values):
"""
Apply the non-affine polar translation transformation.
This method translates points radially outward from the center of the Smith chart by a
specified padding distance. For the y-axis, an additional shift proportional to the font
size is applied.
The center of the Smith chart is assumed to be at [0.5, 0.5] in axis coordinates.
For the y-coordinate, the translation is `pad + 0.5 * font_size`.
Args:
values (array-like):
A single point (x, y) or a list of points to transform.
Returns:
list or tuple:
The transformed points, translated outward from the center.
"""
def _translate(_xy):
x, y = _xy
ang = np.angle(complex(x - x0, y - y0))
return (
x + np.cos(ang) * self.pad,
y + np.sin(ang) * (self.pad + 0.5 * self.font_size),
)
x0, y0 = self.axes.transAxes.transform([0.5, 0.5])
if isinstance(values[0], Iterable):
return list(map(_translate, values))
return _translate(values)
[docs]
def inverted(self):
"""
Return the inverse transformation.
The inverse transformation moves points radially inward toward the center of the Smith chart,
reversing the effect of the outward translation applied by this transformation.
Returns:
PolarTranslateInverse:
An instance of the inverse transformation.
"""
return PolarTranslateInverse(self.axes, self.pad, self.font_size)