diff --git a/CITATION.cff b/CITATION.cff index 1998581d..7e674bd9 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -20,5 +20,5 @@ keywords: - graphs - plotting license: MIT -version: 0.20.2 -date-released: '2026-03-31' +version: 0.20.3 +date-released: '2026-04-30' diff --git a/docs/changelog.md b/docs/changelog.md index c67bd3df..c0b829bb 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -12,6 +12,7 @@ - Optimizes coordinate conversions - Makes constellation lines straight - [**v0.20.2**] Restricts Pandas to version `2.2.3` or lower +- [**v0.20.3**] Fixes bugs with styling and class variables ## v0.19.x [Documentation](https://archives.starplot.dev/0.19.6/) diff --git a/src/starplot/__init__.py b/src/starplot/__init__.py index 2b65fcce..1e46bcb6 100644 --- a/src/starplot/__init__.py +++ b/src/starplot/__init__.py @@ -2,7 +2,7 @@ """Star charts and maps of the sky""" -__version__ = "0.20.2" +__version__ = "0.20.3" from .plots import ( MapPlot, diff --git a/src/starplot/plots/base.py b/src/starplot/plots/base.py index 76591484..b87abb8e 100644 --- a/src/starplot/plots/base.py +++ b/src/starplot/plots/base.py @@ -51,37 +51,9 @@ class BasePlot(DebugPlotterMixin, TextPlotterMixin, ABC): - _background_clip_path = None - _clip_path_polygon: Polygon = None # clip path in display coordinates _coordinate_system = CoordinateSystem.RA_DEC _gradient_direction: GradientDirection = GradientDirection.LINEAR - ax: Axes - """ - The underlying [Matplotlib axes](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.html#matplotlib.axes.Axes) that everything is plotted on. - - **Important**: Most Starplot plotting functions also specify a transform based on the plot's projection when plotting things on the Matplotlib Axes instance, so use this property at your own risk! - """ - - fig: Figure - """ - The underlying [Matplotlib figure](https://matplotlib.org/stable/api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure) that the axes is drawn on. - """ - - style: PlotStyle - """ - The plot's style. - """ - - point_label_handler: CollisionHandler - """Default [collision handler][starplot.CollisionHandler] for point labels.""" - - area_label_handler: CollisionHandler - """Default [collision handler][starplot.CollisionHandler] for area labels.""" - - path_label_handler: CollisionHandler - """Default [collision handler][starplot.CollisionHandler] for path labels.""" - def __init__( self, observer: Observer = None, @@ -99,6 +71,20 @@ def __init__( ): super().__init__(*args, **kwargs) + self._clip_path_polygon: Polygon = None # clip path in display coordinates + + self.ax: Axes = None + """ + The underlying [Matplotlib axes](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.html#matplotlib.axes.Axes) that everything is plotted on. + + **Important**: Most Starplot plotting functions also specify a transform based on the plot's projection when plotting things on the Matplotlib Axes instance, so use this property at your own risk! + """ + + self.fig: Figure = None + """ + The underlying [Matplotlib figure](https://matplotlib.org/stable/api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure) that the axes is drawn on. + """ + if StarplotSettings.svg_text_type == SvgTextType.PATH: plt.rcParams["svg.fonttype"] = "path" else: @@ -111,6 +97,8 @@ def __init__( self.language = StarplotSettings.language self.style = style or PlotStyle() + """The plot's style.""" + self.figure_size = resolution * px self.resolution = resolution @@ -127,12 +115,17 @@ def __init__( AnchorPointEnum.LEFT_CENTER, ], ) + """Default [collision handler][starplot.CollisionHandler] for point labels.""" + self.area_label_handler = area_label_handler or CollisionHandler( allow_constellation_line_collisions=True ) + """Default [collision handler][starplot.CollisionHandler] for area labels.""" + self.path_label_handler = path_label_handler or CollisionHandler( allow_constellation_line_collisions=True ) + """Default [collision handler][starplot.CollisionHandler] for path labels.""" self.scale = scale self.autoscale = autoscale diff --git a/src/starplot/styles/helpers.py b/src/starplot/styles/helpers.py index 17f3a645..61709cf6 100644 --- a/src/starplot/styles/helpers.py +++ b/src/starplot/styles/helpers.py @@ -1,3 +1,4 @@ +import inspect import json from functools import wraps @@ -22,9 +23,13 @@ def merge_dict(dict_1: dict, dict_2: dict) -> None: def use_style(style_class, style_attr: str = None): def decorator(func): + params = list(inspect.signature(func).parameters.keys()) + style_pos = params.index("style") if "style" in params else -1 + @wraps(func) def wrapper(*args, **kwargs): - style = kwargs.get("style") + style_in_positional = 0 <= style_pos < len(args) + style = args[style_pos] if style_in_positional else kwargs.get("style") style_kwargs = { kw: value for kw, value in kwargs.items() if kw.startswith("style__") } @@ -78,6 +83,9 @@ def wrapper(*args, **kwargs): # if no style overrides and there's a base style, then just pass the base style kwargs["style"] = getattr(args[0].style, style_attr, None) + elif style is None and not style_in_positional: + kwargs["style"] = style_class() + return func(*args, **kwargs) return wrapper diff --git a/tests/test_map.py b/tests/test_map.py index 2f843e92..e1e0ff8f 100644 --- a/tests/test_map.py +++ b/tests/test_map.py @@ -72,6 +72,11 @@ def test_marker_no_label(): p.marker(ra=150, dec=0, style__marker__color="blue") +def test_text_no_style_kwarg(): + p = MapPlot(projection=Mercator()) + p.text(ra=100, dec=0, text="hello") + + def test_plots_at_astrometric(): """Asserts that map plots plot astrometric positions, NOT apparent"""