starplot 0.12.4__py2.py3-none-any.whl → 0.13.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of starplot might be problematic. Click here for more details.

Files changed (63) hide show
  1. starplot/__init__.py +1 -1
  2. starplot/base.py +371 -60
  3. starplot/callables.py +61 -7
  4. starplot/data/bayer.py +1532 -3
  5. starplot/data/flamsteed.py +2682 -0
  6. starplot/data/library/constellation_borders_inv.gpkg +0 -0
  7. starplot/data/library/constellation_lines_hips.json +3 -1
  8. starplot/data/stars.py +408 -87
  9. starplot/horizon.py +398 -0
  10. starplot/map.py +149 -24
  11. starplot/models/constellation.py +1 -0
  12. starplot/optic.py +26 -14
  13. starplot/plotters/dsos.py +6 -2
  14. starplot/plotters/stars.py +114 -13
  15. starplot/styles/base.py +263 -156
  16. starplot/styles/ext/antique.yml +45 -39
  17. starplot/styles/ext/blue_dark.yml +32 -36
  18. starplot/styles/ext/blue_light.yml +43 -25
  19. starplot/styles/ext/blue_medium.yml +48 -44
  20. starplot/styles/ext/cb_wong.yml +7 -0
  21. starplot/styles/ext/grayscale.yml +13 -7
  22. starplot/styles/ext/grayscale_dark.yml +12 -4
  23. starplot/styles/ext/map.yml +4 -4
  24. starplot/styles/ext/nord.yml +32 -32
  25. starplot/styles/ext/optic.yml +7 -5
  26. starplot/styles/fonts-library/gfs-didot/DESCRIPTION.en_us.html +9 -0
  27. starplot/styles/fonts-library/gfs-didot/GFSDidot-Regular.ttf +0 -0
  28. starplot/styles/fonts-library/gfs-didot/METADATA.pb +16 -0
  29. starplot/styles/fonts-library/gfs-didot/OFL.txt +94 -0
  30. starplot/styles/fonts-library/hind/DESCRIPTION.en_us.html +28 -0
  31. starplot/styles/fonts-library/hind/Hind-Bold.ttf +0 -0
  32. starplot/styles/fonts-library/hind/Hind-Light.ttf +0 -0
  33. starplot/styles/fonts-library/hind/Hind-Medium.ttf +0 -0
  34. starplot/styles/fonts-library/hind/Hind-Regular.ttf +0 -0
  35. starplot/styles/fonts-library/hind/Hind-SemiBold.ttf +0 -0
  36. starplot/styles/fonts-library/hind/METADATA.pb +58 -0
  37. starplot/styles/fonts-library/hind/OFL.txt +93 -0
  38. starplot/styles/fonts-library/inter/Inter-Black.ttf +0 -0
  39. starplot/styles/fonts-library/inter/Inter-BlackItalic.ttf +0 -0
  40. starplot/styles/fonts-library/inter/Inter-Bold.ttf +0 -0
  41. starplot/styles/fonts-library/inter/Inter-BoldItalic.ttf +0 -0
  42. starplot/styles/fonts-library/inter/Inter-ExtraBold.ttf +0 -0
  43. starplot/styles/fonts-library/inter/Inter-ExtraBoldItalic.ttf +0 -0
  44. starplot/styles/fonts-library/inter/Inter-ExtraLight.ttf +0 -0
  45. starplot/styles/fonts-library/inter/Inter-ExtraLightItalic.ttf +0 -0
  46. starplot/styles/fonts-library/inter/Inter-Italic.ttf +0 -0
  47. starplot/styles/fonts-library/inter/Inter-Light.ttf +0 -0
  48. starplot/styles/fonts-library/inter/Inter-LightItalic.ttf +0 -0
  49. starplot/styles/fonts-library/inter/Inter-Medium.ttf +0 -0
  50. starplot/styles/fonts-library/inter/Inter-MediumItalic.ttf +0 -0
  51. starplot/styles/fonts-library/inter/Inter-Regular.ttf +0 -0
  52. starplot/styles/fonts-library/inter/Inter-SemiBold.ttf +0 -0
  53. starplot/styles/fonts-library/inter/Inter-SemiBoldItalic.ttf +0 -0
  54. starplot/styles/fonts-library/inter/Inter-Thin.ttf +0 -0
  55. starplot/styles/fonts-library/inter/Inter-ThinItalic.ttf +0 -0
  56. starplot/styles/fonts-library/inter/LICENSE.txt +92 -0
  57. starplot/styles/fonts.py +15 -0
  58. starplot/styles/markers.py +207 -6
  59. {starplot-0.12.4.dist-info → starplot-0.13.0.dist-info}/METADATA +9 -10
  60. starplot-0.13.0.dist-info/RECORD +101 -0
  61. starplot-0.12.4.dist-info/RECORD +0 -67
  62. {starplot-0.12.4.dist-info → starplot-0.13.0.dist-info}/LICENSE +0 -0
  63. {starplot-0.12.4.dist-info → starplot-0.13.0.dist-info}/WHEEL +0 -0
starplot/map.py CHANGED
@@ -14,7 +14,7 @@ import geopandas as gpd
14
14
  import numpy as np
15
15
 
16
16
  from starplot import geod
17
- from starplot.base import BasePlot
17
+ from starplot.base import BasePlot, DPI
18
18
  from starplot.data import DataFiles, constellations as condata, stars
19
19
  from starplot.data.constellations import CONSTELLATIONS_FULL_NAMES
20
20
  from starplot.mixins import ExtentMaskMixin
@@ -28,7 +28,6 @@ from starplot.styles import (
28
28
  PlotStyle,
29
29
  PolygonStyle,
30
30
  PathStyle,
31
- extensions,
32
31
  )
33
32
  from starplot.styles.helpers import use_style
34
33
  from starplot.utils import lon_to_ra, ra_to_lon
@@ -37,7 +36,25 @@ from starplot.utils import lon_to_ra, ra_to_lon
37
36
  warnings.filterwarnings("ignore", module="cartopy")
38
37
  warnings.filterwarnings("ignore", module="shapely")
39
38
 
40
- DEFAULT_MAP_STYLE = PlotStyle().extend(extensions.MAP)
39
+ DEFAULT_MAP_STYLE = PlotStyle() # .extend(extensions.MAP)
40
+
41
+
42
+ def points(start, end, num_points=100):
43
+ """Generates points along a line segment.
44
+
45
+ Args:
46
+ start (tuple): (x, y) coordinates of the starting point.
47
+ end (tuple): (x, y) coordinates of the ending point.
48
+ num_points (int): Number of points to generate.
49
+
50
+ Returns:
51
+ list: List of (x, y) coordinates of the generated points.
52
+ """
53
+
54
+ x_coords = np.linspace(start[0], end[0], num_points)
55
+ y_coords = np.linspace(start[1], end[1], num_points)
56
+
57
+ return list(zip(x_coords, y_coords))
41
58
 
42
59
 
43
60
  class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
@@ -60,6 +77,8 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
60
77
  resolution: Size (in pixels) of largest dimension of the map
61
78
  hide_colliding_labels: If True, then labels will not be plotted if they collide with another existing label
62
79
  clip_path: An optional Shapely Polygon that specifies the clip path of the plot -- only objects inside the polygon will be plotted. If `None` (the default), then the clip path will be the extent of the map you specified with the RA/DEC parameters.
80
+ scale: Scaling factor that will be applied to all sizes in styles (e.g. font size, marker size, line widths, etc). For example, if you want to make everything 2x bigger, then set the scale to 2. At `scale=1` and `resolution=4096` (the default), all sizes are optimized visually for a map that covers 1-3 constellations. So, if you're creating a plot of a _larger_ extent, then it'd probably be good to decrease the scale (i.e. make everything smaller) -- and _increase_ the scale if you're plotting a very small area.
81
+ autoscale: If True, then the scale will be set automatically based on resolution.
63
82
 
64
83
  Returns:
65
84
  MapPlot: A new instance of a MapPlot
@@ -78,9 +97,11 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
78
97
  dt: datetime = None,
79
98
  ephemeris: str = "de421_2001.bsp",
80
99
  style: PlotStyle = DEFAULT_MAP_STYLE,
81
- resolution: int = 2048,
100
+ resolution: int = 4096,
82
101
  hide_colliding_labels: bool = True,
83
102
  clip_path: Polygon = None,
103
+ scale: float = 1.0,
104
+ autoscale: bool = False,
84
105
  *args,
85
106
  **kwargs,
86
107
  ) -> "MapPlot":
@@ -90,6 +111,8 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
90
111
  style,
91
112
  resolution,
92
113
  hide_colliding_labels,
114
+ scale=scale,
115
+ autoscale=autoscale,
93
116
  *args,
94
117
  **kwargs,
95
118
  )
@@ -249,7 +272,7 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
249
272
  if constellation_borders.empty:
250
273
  return
251
274
 
252
- style_kwargs = style.matplot_kwargs(self._size_multiplier)
275
+ style_kwargs = style.matplot_kwargs(self.scale)
253
276
 
254
277
  geometries = []
255
278
 
@@ -265,6 +288,7 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
265
288
  transform=self._plate_carree,
266
289
  clip_on=True,
267
290
  clip_path=self._background_clip_path,
291
+ gid="constellations-border",
268
292
  **style_kwargs,
269
293
  )
270
294
 
@@ -325,9 +349,7 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
325
349
  mls = MultiLineString(geometries)
326
350
  geometries = unary_union(mls)
327
351
 
328
- style_kwargs = self.style.constellation_borders.matplot_kwargs(
329
- size_multiplier=self._size_multiplier
330
- )
352
+ style_kwargs = self.style.constellation_borders.matplot_kwargs(self.scale)
331
353
 
332
354
  for ls in list(geometries.geoms):
333
355
  # print(ls)
@@ -350,7 +372,9 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
350
372
  labels: dict[str, str] = CONSTELLATIONS_FULL_NAMES,
351
373
  where: list = None,
352
374
  ):
353
- """Plots the constellation lines and/or labels
375
+ """Plots the constellation lines and/or labels.
376
+
377
+ **Important:** If you're plotting the constellation lines, then it's good to plot them _first_, because Starplot will use the constellation lines to determine where to place labels that are plotted afterwards (labels will look better if they're not crossing a constellation line).
354
378
 
355
379
  Args:
356
380
  style: Styling of the constellations. If None, then the plot's style (specified when creating the plot) will be used
@@ -379,7 +403,7 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
379
403
  transform = self._geodetic
380
404
 
381
405
  conline_hips = condata.lines()
382
- style_kwargs = style.line.matplot_kwargs(size_multiplier=self._size_multiplier)
406
+ style_kwargs = style.line.matplot_kwargs(self.scale)
383
407
 
384
408
  for c in constellations_gdf.itertuples():
385
409
  obj = constellation_from_tuple(c)
@@ -416,19 +440,45 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
416
440
  # s1_ra, s1_dec = self._proj.transform_point(s1_ra, s1.dec_degrees, self._geodetic)
417
441
  # s2_ra, s2_dec = self._proj.transform_point(s2_ra, s2.dec_degrees, self._geodetic)
418
442
 
419
- self.ax.plot(
443
+ constellation_line = self.ax.plot(
420
444
  [s1_ra, s2_ra],
421
445
  [s1_dec, s2_dec],
422
446
  transform=transform,
423
447
  **style_kwargs,
424
448
  clip_on=True,
425
449
  clip_path=self._background_clip_path,
450
+ gid="constellations-line",
451
+ )[0]
452
+
453
+ extent = constellation_line.get_window_extent(
454
+ renderer=self.fig.canvas.get_renderer()
426
455
  )
427
456
 
457
+ if extent.xmin < 0:
458
+ continue
459
+
460
+ start = self._proj.transform_point(s1_ra, s1_dec, self._geodetic)
461
+ end = self._proj.transform_point(s2_ra, s2_dec, self._geodetic)
462
+ radius = style_kwargs.get("linewidth") or 1
463
+
464
+ if any([np.isnan(n) for n in start + end]):
465
+ continue
466
+
467
+ for x, y in points(start, end, 25):
468
+ x0, y0 = self.ax.transData.transform((x, y))
469
+ if x0 < 0 or y0 < 0:
470
+ continue
471
+ self._constellations_rtree.insert(
472
+ 0,
473
+ np.array((x0 - radius, y0 - radius, x0 + radius, y0 + radius)),
474
+ obj=obj.name,
475
+ )
476
+
428
477
  if inbounds:
429
478
  self._objects.constellations.append(obj)
430
479
 
431
480
  self._plot_constellation_labels(style.label, labels)
481
+ # self._plot_constellation_labels_experimental(style.label, labels)
432
482
 
433
483
  def _plot_constellation_labels(
434
484
  self,
@@ -440,6 +490,75 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
440
490
  for con in condata.iterator():
441
491
  _, ra, dec = condata.get(con)
442
492
  text = labels.get(con.lower())
493
+ self.text(
494
+ text,
495
+ ra,
496
+ dec,
497
+ style,
498
+ hide_on_collision=False,
499
+ gid="constellations-label-name",
500
+ )
501
+
502
+ def _plot_constellation_labels_experimental(
503
+ self,
504
+ style: PathStyle = None,
505
+ labels: dict[str, str] = CONSTELLATIONS_FULL_NAMES,
506
+ ):
507
+ from shapely import (
508
+ MultiPoint,
509
+ intersection,
510
+ delaunay_triangles,
511
+ distance,
512
+ )
513
+
514
+ def sorter(g):
515
+ d = distance(g.centroid, points.centroid)
516
+ # d = distance(g.centroid, constellation.boundary.centroid)
517
+ extent = abs(g.bounds[2] - g.bounds[0])
518
+ area = g.area / constellation.boundary.area
519
+ return (extent**2 + area) - (d**2)
520
+
521
+ for constellation in self.objects.constellations:
522
+ constellation_stars = [
523
+ s
524
+ for s in self.objects.stars
525
+ if s.constellation_id == constellation.iau_id
526
+ ]
527
+ points = MultiPoint([(s.ra, s.dec) for s in constellation_stars])
528
+
529
+ triangles = delaunay_triangles(
530
+ geometry=points,
531
+ # tolerance=2,
532
+ )
533
+
534
+ polygons = []
535
+ for t in triangles.geoms:
536
+ try:
537
+ inter = intersection(t, constellation.boundary)
538
+ except Exception:
539
+ continue
540
+ if (
541
+ inter.geom_type == "Polygon"
542
+ and len(list(zip(*inter.exterior.coords.xy))) > 2
543
+ ):
544
+ polygons.append(inter)
545
+
546
+ p_by_area = {pg.area: pg for pg in polygons}
547
+ polygons_sorted = [
548
+ p_by_area[k] for k in sorted(p_by_area.keys(), reverse=True)
549
+ ]
550
+
551
+ # sort by combination of horizontal extent and area
552
+ polygons_sorted = sorted(polygons_sorted, key=sorter, reverse=True)
553
+
554
+ if len(polygons_sorted) > 0:
555
+ i = 0
556
+ ra, dec = polygons_sorted[i].centroid.x, polygons_sorted[i].centroid.y
557
+ else:
558
+ ra, dec = constellation.ra, constellation.dec
559
+
560
+ text = labels.get(constellation.iau_id)
561
+ style = style or self.style.constellation.label
443
562
  self.text(text, ra, dec, style)
444
563
 
445
564
  @use_style(PolygonStyle, "milky_way")
@@ -499,11 +618,11 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
499
618
  ra, dec, _ = zenith.radec()
500
619
 
501
620
  self.marker(
502
- ra.hours,
503
- dec.degrees,
504
- label,
505
- style,
506
- legend_label,
621
+ ra=ra.hours,
622
+ dec=dec.degrees,
623
+ style=style,
624
+ label=label,
625
+ legend_label=legend_label,
507
626
  )
508
627
 
509
628
  @use_style(PathStyle, "horizon")
@@ -554,7 +673,7 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
554
673
 
555
674
  TODO : investigate why line is extra thick on bottom when plotting line
556
675
  """
557
- style_kwargs = style.line.matplot_kwargs(self._size_multiplier)
676
+ style_kwargs = style.line.matplot_kwargs(self.scale)
558
677
  style_kwargs["clip_on"] = False
559
678
  style_kwargs["edgecolor"] = style_kwargs.pop("color")
560
679
 
@@ -574,7 +693,7 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
574
693
  x,
575
694
  y,
576
695
  dash_capstyle=style.line.dash_capstyle,
577
- **style.line.matplot_kwargs(self._size_multiplier),
696
+ **style.line.matplot_kwargs(self.scale),
578
697
  **style_kwargs,
579
698
  **self._plot_kwargs(),
580
699
  )
@@ -597,10 +716,13 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
597
716
  cardinal_directions = [north, east, south, west]
598
717
 
599
718
  text_kwargs = dict(
600
- **style.label.matplot_kwargs(self._size_multiplier),
719
+ **style.label.matplot_kwargs(self.scale),
601
720
  hide_on_collision=False,
602
- xytext=(style.label.offset_x, style.label.offset_y),
603
- textcoords="offset pixels",
721
+ xytext=(
722
+ style.label.offset_x * self.scale,
723
+ style.label.offset_y * self.scale,
724
+ ),
725
+ textcoords="offset points",
604
726
  path_effects=[],
605
727
  )
606
728
 
@@ -609,7 +731,7 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
609
731
 
610
732
  for i, position in enumerate(cardinal_directions):
611
733
  ra, dec, _ = position.radec()
612
- self._text(ra.hours, dec.degrees, labels[i], **text_kwargs)
734
+ self._text(ra.hours, dec.degrees, labels[i], force=True, **text_kwargs)
613
735
 
614
736
  @use_style(PathStyle, "gridlines")
615
737
  def gridlines(
@@ -664,6 +786,7 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
664
786
  ypadding=12,
665
787
  clip_on=True,
666
788
  clip_path=self._background_clip_path,
789
+ gid="gridlines",
667
790
  **line_style_kwargs,
668
791
  )
669
792
 
@@ -681,6 +804,7 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
681
804
  self.ax.plot(
682
805
  (ra * 15, ra * 15),
683
806
  (-90, 90),
807
+ gid="gridlines",
684
808
  **line_style_kwargs,
685
809
  **self._plot_kwargs(),
686
810
  )
@@ -732,6 +856,7 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
732
856
  figsize=(self.figure_size, self.figure_size),
733
857
  facecolor=self.style.figure_background_color.as_hex(),
734
858
  layout="constrained",
859
+ dpi=DPI,
735
860
  )
736
861
  bounds = self._latlon_bounds()
737
862
  center_lat = (bounds[2] + bounds[3]) / 2
@@ -800,7 +925,7 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
800
925
  0.05,
801
926
  info,
802
927
  transform=self.ax.transAxes,
803
- **style.matplot_kwargs(self._size_multiplier * 1.36),
928
+ **style.matplot_kwargs(self.scale),
804
929
  )
805
930
 
806
931
  def _plot_background_clip_path(self):
@@ -830,7 +955,7 @@ class MapPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
830
955
  fill=True,
831
956
  facecolor=self.style.background_color.as_hex(),
832
957
  # edgecolor=self.style.border_line_color.as_hex(),
833
- linewidth=0, # 4 * self._size_multiplier,
958
+ linewidth=0,
834
959
  zorder=-2_000,
835
960
  transform=self.ax.transAxes,
836
961
  )
@@ -39,6 +39,7 @@ class Constellation(SkyObject):
39
39
  ) -> None:
40
40
  super().__init__(ra, dec)
41
41
  self.iau_id = iau_id.lower()
42
+ self.constellation_id = self.iau_id # override from super()
42
43
  self.name = name
43
44
  self.boundary = boundary
44
45
 
starplot/optic.py CHANGED
@@ -8,7 +8,7 @@ from matplotlib import pyplot as plt, patches, path
8
8
  from skyfield.api import wgs84, Star as SkyfieldStar
9
9
 
10
10
  from starplot import callables
11
- from starplot.base import BasePlot
11
+ from starplot.base import BasePlot, DPI
12
12
  from starplot.data.stars import StarCatalog, STAR_NAMES
13
13
  from starplot.mixins import ExtentMaskMixin
14
14
  from starplot.models import Star
@@ -44,6 +44,8 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
44
44
  resolution: Size (in pixels) of largest dimension of the map
45
45
  hide_colliding_labels: If True, then labels will not be plotted if they collide with another existing label
46
46
  raise_on_below_horizon: If True, then a ValueError will be raised if the target is below the horizon at the observing time/location
47
+ scale: Scaling factor that will be applied to all sizes in styles (e.g. font size, marker size, line widths, etc). For example, if you want to make everything 2x bigger, then set the scale to 2. At `scale=1` and `resolution=4096` (the default), all sizes are optimized visually for a map that covers 1-3 constellations. So, if you're creating a plot of a _larger_ extent, then it'd probably be good to decrease the scale (i.e. make everything smaller) -- and _increase_ the scale if you're plotting a very small area.
48
+ autoscale: If True, then the scale will be set automatically based on resolution.
47
49
 
48
50
  Returns:
49
51
  OpticPlot: A new instance of an OpticPlot
@@ -62,9 +64,11 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
62
64
  dt: datetime = None,
63
65
  ephemeris: str = "de421_2001.bsp",
64
66
  style: PlotStyle = DEFAULT_OPTIC_STYLE,
65
- resolution: int = 2048,
67
+ resolution: int = 4096,
66
68
  hide_colliding_labels: bool = True,
67
69
  raise_on_below_horizon: bool = True,
70
+ scale: float = 1.0,
71
+ autoscale: bool = False,
68
72
  *args,
69
73
  **kwargs,
70
74
  ) -> "OpticPlot":
@@ -74,6 +78,8 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
74
78
  style,
75
79
  resolution,
76
80
  hide_colliding_labels,
81
+ scale=scale,
82
+ autoscale=autoscale,
77
83
  *args,
78
84
  **kwargs,
79
85
  )
@@ -193,6 +199,7 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
193
199
  else:
194
200
  plotted.set_clip_path(self._background_clip_path)
195
201
 
202
+ @use_style(ObjectStyle, "star")
196
203
  def stars(
197
204
  self,
198
205
  mag: float = 6.0,
@@ -207,6 +214,7 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
207
214
  labels: Mapping[int, str] = STAR_NAMES,
208
215
  legend_label: str = "Star",
209
216
  bayer_labels: bool = False,
217
+ flamsteed_labels: bool = False,
210
218
  *args,
211
219
  **kwargs,
212
220
  ):
@@ -225,12 +233,16 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
225
233
  where_labels: A list of expressions that determine which stars are labeled on the plot. See [Selecting Objects](/reference-selecting-objects/) for details.
226
234
  labels: A dictionary that maps a star's HIP id to the label that'll be plotted for that star. If you want to hide name labels, then set this arg to `None`.
227
235
  legend_label: Label for stars in the legend. If `None`, then they will not be in the legend.
228
- bayer_labels: If True, then Bayer labels for stars will be plotted. Set this to False if you want to hide Bayer labels.
236
+ bayer_labels: If True, then Bayer labels for stars will be plotted.
237
+ flamsteed_labels: If True, then Flamsteed number labels for stars will be plotted.
229
238
  """
230
- optic_star_multiplier = 0.4 * (self.FIELD_OF_VIEW_MAX / self.optic.true_fov)
239
+ optic_star_multiplier = self.FIELD_OF_VIEW_MAX / self.optic.true_fov
240
+ size_fn_mx = None
231
241
 
232
- def size_fn_mx(st: Star) -> float:
233
- return size_fn(st) * optic_star_multiplier
242
+ if size_fn is not None:
243
+
244
+ def size_fn_mx(s):
245
+ return size_fn(s) * optic_star_multiplier
234
246
 
235
247
  super().stars(
236
248
  mag=mag,
@@ -245,6 +257,7 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
245
257
  labels=labels,
246
258
  legend_label=legend_label,
247
259
  bayer_labels=bayer_labels,
260
+ flamsteed_labels=flamsteed_labels,
248
261
  *args,
249
262
  **kwargs,
250
263
  )
@@ -268,7 +281,7 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
268
281
  ) # apply transform again because new xy limits will undo the transform
269
282
 
270
283
  dt_str = self.dt.strftime("%m/%d/%Y @ %H:%M:%S") + " " + self.dt.tzname()
271
- font_size = style.font_size * self._size_multiplier * 2
284
+ font_size = style.font_size * self.scale
272
285
 
273
286
  column_labels = [
274
287
  "Target (Alt/Az)",
@@ -296,19 +309,17 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
296
309
  edges="vertical",
297
310
  )
298
311
  table.auto_set_font_size(False)
299
- table.set_fontsize(font_size)
312
+ table.set_fontsize(style.font_size)
300
313
  table.scale(1, 3.1)
301
314
 
302
315
  # Apply style to all cells
303
316
  for row in [0, 1]:
304
317
  for col in range(len(values)):
305
- table[row, col].set_text_props(
306
- **style.matplot_kwargs(self._size_multiplier)
307
- )
318
+ table[row, col].set_text_props(**style.matplot_kwargs(self.scale))
308
319
 
309
320
  # Apply some styles only to the header row
310
321
  for col in range(len(values)):
311
- table[0, col].set_text_props(fontweight="heavy", fontsize=font_size * 1.15)
322
+ table[0, col].set_text_props(fontweight="heavy", fontsize=font_size * 1.2)
312
323
 
313
324
  def _plot_border(self):
314
325
  # since we're using AzimuthalEquidistant projection, the center will always be (0, 0)
@@ -330,7 +341,7 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
330
341
  inner_border = self.optic.patch(
331
342
  x,
332
343
  y,
333
- linewidth=2 * self._size_multiplier,
344
+ linewidth=2 * self.scale,
334
345
  edgecolor=self.style.border_line_color.as_hex(),
335
346
  fill=False,
336
347
  zorder=ZOrderEnum.LAYER_5 + 100,
@@ -342,7 +353,7 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
342
353
  x,
343
354
  y,
344
355
  padding=0.05,
345
- linewidth=20 * self._size_multiplier,
356
+ linewidth=20 * self.scale,
346
357
  edgecolor=self.style.border_bg_color.as_hex(),
347
358
  fill=False,
348
359
  zorder=ZOrderEnum.LAYER_5,
@@ -366,6 +377,7 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
366
377
  figsize=(self.figure_size, self.figure_size),
367
378
  facecolor=self.style.figure_background_color.as_hex(),
368
379
  layout="constrained",
380
+ dpi=DPI,
369
381
  )
370
382
  self.ax = plt.axes(projection=self._proj)
371
383
  self.ax.xaxis.set_visible(False)
starplot/plotters/dsos.py CHANGED
@@ -222,16 +222,20 @@ class DsoPlotterMixin:
222
222
  )
223
223
 
224
224
  if label:
225
- self.text(label, ra / 15, dec, style.label)
225
+ self.text(
226
+ label, ra / 15, dec, style.label, gid=f"dso-{d.type}-label"
227
+ )
226
228
 
227
229
  else:
228
230
  # if no major axis, then just plot as a marker
229
231
  self.marker(
230
232
  ra=ra / 15,
231
233
  dec=dec,
232
- label=label,
233
234
  style=style,
235
+ label=label,
234
236
  skip_bounds_check=True,
237
+ gid_marker=f"dso-{d.type}-marker",
238
+ gid_label=f"dso-{d.type}-label",
235
239
  )
236
240
 
237
241
  self._objects.dsos.append(_dso)