starplot 0.13.0__py2.py3-none-any.whl → 0.15.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.
Files changed (74) hide show
  1. starplot/__init__.py +5 -2
  2. starplot/base.py +311 -197
  3. starplot/cli.py +33 -0
  4. starplot/coordinates.py +6 -0
  5. starplot/data/__init__.py +6 -24
  6. starplot/data/bigsky.py +58 -40
  7. starplot/data/constellation_lines.py +827 -0
  8. starplot/data/constellation_stars.py +1501 -0
  9. starplot/data/constellations.py +600 -27
  10. starplot/data/db.py +17 -0
  11. starplot/data/dsos.py +24 -141
  12. starplot/data/stars.py +45 -24
  13. starplot/geod.py +0 -6
  14. starplot/geometry.py +181 -0
  15. starplot/horizon.py +302 -231
  16. starplot/map.py +100 -463
  17. starplot/mixins.py +75 -14
  18. starplot/models/__init__.py +1 -1
  19. starplot/models/base.py +18 -129
  20. starplot/models/constellation.py +55 -32
  21. starplot/models/dso.py +132 -67
  22. starplot/models/moon.py +57 -78
  23. starplot/models/planet.py +44 -69
  24. starplot/models/star.py +91 -60
  25. starplot/models/sun.py +32 -53
  26. starplot/optic.py +21 -18
  27. starplot/plotters/__init__.py +2 -0
  28. starplot/plotters/constellations.py +342 -0
  29. starplot/plotters/dsos.py +49 -68
  30. starplot/plotters/experimental.py +171 -0
  31. starplot/plotters/milkyway.py +39 -0
  32. starplot/plotters/stars.py +126 -122
  33. starplot/profile.py +16 -0
  34. starplot/settings.py +26 -0
  35. starplot/styles/__init__.py +2 -0
  36. starplot/styles/base.py +56 -34
  37. starplot/styles/ext/antique.yml +11 -9
  38. starplot/styles/ext/blue_dark.yml +8 -10
  39. starplot/styles/ext/blue_gold.yml +135 -0
  40. starplot/styles/ext/blue_light.yml +14 -12
  41. starplot/styles/ext/blue_medium.yml +23 -20
  42. starplot/styles/ext/cb_wong.yml +9 -7
  43. starplot/styles/ext/grayscale.yml +4 -3
  44. starplot/styles/ext/grayscale_dark.yml +7 -5
  45. starplot/styles/ext/map.yml +9 -6
  46. starplot/styles/ext/nord.yml +7 -7
  47. starplot/styles/ext/optic.yml +1 -1
  48. starplot/styles/extensions.py +1 -0
  49. starplot/utils.py +19 -0
  50. starplot/warnings.py +21 -0
  51. {starplot-0.13.0.dist-info → starplot-0.15.0.dist-info}/METADATA +19 -18
  52. starplot-0.15.0.dist-info/RECORD +97 -0
  53. starplot-0.15.0.dist-info/entry_points.txt +3 -0
  54. starplot/data/bayer.py +0 -3499
  55. starplot/data/flamsteed.py +0 -2682
  56. starplot/data/library/constellation_borders_inv.gpkg +0 -0
  57. starplot/data/library/constellation_lines_hips.json +0 -709
  58. starplot/data/library/constellation_lines_inv.gpkg +0 -0
  59. starplot/data/library/constellations.gpkg +0 -0
  60. starplot/data/library/constellations_hip.fab +0 -88
  61. starplot/data/library/milkyway.gpkg +0 -0
  62. starplot/data/library/milkyway_inv.gpkg +0 -0
  63. starplot/data/library/ongc.gpkg.zip +0 -0
  64. starplot/data/library/stars.bigsky.mag11.parquet +0 -0
  65. starplot/data/library/stars.hipparcos.parquet +0 -0
  66. starplot/data/messier.py +0 -111
  67. starplot/data/prep/__init__.py +0 -0
  68. starplot/data/prep/constellations.py +0 -108
  69. starplot/data/prep/dsos.py +0 -299
  70. starplot/data/prep/utils.py +0 -16
  71. starplot/models/geometry.py +0 -44
  72. starplot-0.13.0.dist-info/RECORD +0 -101
  73. {starplot-0.13.0.dist-info → starplot-0.15.0.dist-info}/LICENSE +0 -0
  74. {starplot-0.13.0.dist-info → starplot-0.15.0.dist-info}/WHEEL +0 -0
starplot/models/star.py CHANGED
@@ -1,31 +1,12 @@
1
- from typing import Optional
1
+ import math
2
+ from typing import Optional, Union, Iterator
2
3
 
3
4
  import numpy as np
4
5
  from shapely import Point
6
+ from ibis import _
5
7
 
6
- from starplot.models.base import SkyObject, SkyObjectManager
7
- from starplot.data.stars import StarCatalog, STAR_NAMES, load as _load_stars
8
-
9
-
10
- class StarManager(SkyObjectManager):
11
- @classmethod
12
- def all(cls, catalog: StarCatalog = StarCatalog.HIPPARCOS):
13
- all_stars = _load_stars(catalog)
14
-
15
- # TODO : add datetime kwarg
16
-
17
- for s in all_stars.itertuples():
18
- yield from_tuple(s, catalog)
19
-
20
- @classmethod
21
- def find(cls, where, catalog: StarCatalog = StarCatalog.HIPPARCOS):
22
- all_objects = cls.all(catalog)
23
- return super().find(where=where, all_objects=all_objects)
24
-
25
- @classmethod
26
- def get(cls, catalog: StarCatalog = StarCatalog.HIPPARCOS, **kwargs):
27
- all_objects = cls.all(catalog)
28
- return super().get(all_objects=all_objects, **kwargs)
8
+ from starplot.models.base import SkyObject
9
+ from starplot.data.stars import StarCatalog, load as _load_stars
29
10
 
30
11
 
31
12
  class Star(SkyObject):
@@ -33,8 +14,6 @@ class Star(SkyObject):
33
14
  Star model.
34
15
  """
35
16
 
36
- _manager = StarManager
37
-
38
17
  magnitude: float
39
18
  """Magnitude"""
40
19
 
@@ -53,8 +32,14 @@ class Star(SkyObject):
53
32
  name: Optional[str] = None
54
33
  """Name, if available"""
55
34
 
35
+ bayer: Optional[str] = None
36
+ """Bayer designation, if available"""
37
+
38
+ flamsteed: Optional[int] = None
39
+ """Flamsteed number, if available"""
40
+
56
41
  geometry: Point = None
57
- """Shapely Point of the star's position. Right ascension coordinates are in 24H format."""
42
+ """Shapely Point of the star's position. Right ascension coordinates are in degrees (0...360)."""
58
43
 
59
44
  def __init__(
60
45
  self,
@@ -67,69 +52,115 @@ class Star(SkyObject):
67
52
  tyc: str = None,
68
53
  ccdm: str = None,
69
54
  geometry: Point = None,
55
+ constellation_id: str = None,
56
+ bayer: str = None,
57
+ flamsteed: int = None,
70
58
  ) -> None:
71
- super().__init__(ra, dec)
59
+ super().__init__(ra, dec, constellation_id)
72
60
  self.magnitude = magnitude
73
61
  self.bv = bv
74
62
  self.hip = hip if hip is not None and np.isfinite(hip) else None
75
63
  self.name = name
76
64
  self.tyc = tyc
77
65
  self.ccdm = ccdm
78
- self.geometry = Point([ra, dec])
66
+ self.geometry = geometry
67
+
68
+ if bayer:
69
+ self.bayer = bayer
70
+
71
+ if flamsteed and not math.isnan(flamsteed):
72
+ self.flamsteed = int(flamsteed)
79
73
 
80
74
  def __repr__(self) -> str:
81
75
  return f"Star(hip={self.hip}, tyc={self.tyc}, magnitude={self.magnitude}, ra={self.ra}, dec={self.dec})"
82
76
 
83
77
  @classmethod
84
- def get(**kwargs) -> "Star":
78
+ def all(cls, catalog: StarCatalog = StarCatalog.BIG_SKY_MAG11) -> Iterator["Star"]:
79
+ df = _load_stars(catalog=catalog).to_pandas()
80
+
81
+ for s in df.itertuples():
82
+ yield from_tuple(s)
83
+
84
+ @classmethod
85
+ def get(
86
+ cls, catalog: StarCatalog = StarCatalog.BIG_SKY_MAG11, **kwargs
87
+ ) -> Union["Star", None]:
85
88
  """
86
- Get a Star, by matching its attributes.
89
+ Get a Star, by matching its attributes as specified in `**kwargs`
90
+
91
+ Example:
87
92
 
88
- Example: `sirius = Star.get(name="Sirius")`
93
+ sirius = Star.get(name="Sirius")
89
94
 
90
95
  Args:
96
+ catalog: The catalog of stars to use: "big-sky-mag11", or "big-sky" -- see [`StarCatalog`](/reference-data/#starplot.data.stars.StarCatalog) for details
91
97
  **kwargs: Attributes on the star you want to match
92
98
 
93
99
  Raises: `ValueError` if more than one star is matched
100
+
101
+ Returns:
102
+ Star instance if there's exactly one match or `None` if there are zero matches
94
103
  """
95
- pass
104
+ filters = []
105
+
106
+ for k, v in kwargs.items():
107
+ filters.append(getattr(_, k) == v)
108
+
109
+ df = _load_stars(
110
+ catalog=catalog,
111
+ filters=filters,
112
+ ).to_pandas()
113
+
114
+ results = [from_tuple(s) for s in df.itertuples()]
115
+
116
+ if len(results) == 1:
117
+ return results[0]
118
+
119
+ if len(results) > 1:
120
+ raise ValueError(
121
+ "More than one match. Use find() instead or narrow your search."
122
+ )
123
+
124
+ return None
96
125
 
97
126
  @classmethod
98
- def find(where: list) -> list["Star"]:
127
+ def find(
128
+ cls, where: list, catalog: StarCatalog = StarCatalog.BIG_SKY_MAG11
129
+ ) -> list["Star"]:
99
130
  """
100
131
  Find Stars
101
132
 
102
133
  Args:
103
134
  where: A list of expressions that determine which stars to find. See [Selecting Objects](/reference-selecting-objects/) for details.
135
+ catalog: The catalog of stars to use: "big-sky-mag11", or "big-sky" -- see [`StarCatalog`](/reference-data/#starplot.data.stars.StarCatalog) for details
104
136
 
105
137
  Returns:
106
138
  List of Stars that match all `where` expressions
107
139
 
108
140
  """
109
- pass
110
-
111
-
112
- def from_tuple(star: tuple, catalog: StarCatalog) -> Star:
113
- m = star.magnitude
114
- ra, dec = star.ra_hours, star.dec_degrees
115
-
116
- if catalog == StarCatalog.HIPPARCOS:
117
- hip_id = star.Index
118
- tyc_id = None
119
- ccdm = None
120
- else:
121
- hip_id = star.hip
122
- tyc_id = star.Index
123
- ccdm = star.ccdm
124
-
125
- return Star(
126
- ra=ra,
127
- dec=dec,
128
- magnitude=m,
129
- bv=star.bv,
130
- hip=hip_id,
131
- tyc=tyc_id,
132
- ccdm=ccdm,
133
- name=STAR_NAMES.get(hip_id) if np.isfinite(hip_id) else None,
134
- geometry=Point([ra, dec]),
141
+ df = _load_stars(
142
+ catalog=catalog,
143
+ filters=where,
144
+ ).to_pandas()
145
+
146
+ return [from_tuple(s) for s in df.itertuples()]
147
+
148
+
149
+ def from_tuple(star: tuple) -> Star:
150
+ s = Star(
151
+ ra=star.ra,
152
+ dec=star.dec,
153
+ hip=getattr(star, "hip", None),
154
+ magnitude=star.magnitude,
155
+ bv=getattr(star, "bv", None),
156
+ tyc=getattr(star, "tyc_id", None),
157
+ ccdm=getattr(star, "ccdm", None),
158
+ name=getattr(star, "name", None),
159
+ geometry=star.geometry,
160
+ constellation_id=getattr(star, "constellation", None),
161
+ bayer=getattr(star, "bayer", None),
162
+ flamsteed=getattr(star, "flamsteed", None),
135
163
  )
164
+ s._row_id = getattr(star, "rowid", None)
165
+
166
+ return s
starplot/models/sun.py CHANGED
@@ -5,63 +5,14 @@ from skyfield.api import Angle, wgs84
5
5
  from shapely import Polygon
6
6
 
7
7
  from starplot.data import load
8
- from starplot.models.base import SkyObject, SkyObjectManager
9
- from starplot.models.geometry import circle
8
+ from starplot.models.base import SkyObject
9
+ from starplot.geometry import circle
10
10
  from starplot.utils import dt_or_now
11
11
 
12
12
 
13
- class SunManager(SkyObjectManager):
14
- @classmethod
15
- def all(cls):
16
- raise NotImplementedError
17
-
18
- @classmethod
19
- def find(cls):
20
- raise NotImplementedError
21
-
22
- @classmethod
23
- def get(
24
- cls,
25
- dt: datetime = None,
26
- lat: float = None,
27
- lon: float = None,
28
- ephemeris: str = "de421_2001.bsp",
29
- ) -> "Sun":
30
- RADIUS_KM = 695_700
31
-
32
- dt = dt_or_now(dt)
33
- ephemeris = load(ephemeris)
34
- timescale = load.timescale().from_datetime(dt)
35
- earth, sun = ephemeris["earth"], ephemeris["sun"]
36
-
37
- if lat is not None and lon is not None:
38
- position = earth + wgs84.latlon(lat, lon)
39
- astrometric = position.at(timescale).observe(sun)
40
- apparent = astrometric.apparent()
41
- ra, dec, distance = apparent.radec()
42
- else:
43
- astrometric = earth.at(timescale).observe(sun)
44
- ra, dec, distance = astrometric.radec()
45
-
46
- apparent_diameter_degrees = Angle(
47
- radians=np.arcsin(RADIUS_KM / distance.km) * 2.0
48
- ).degrees
49
-
50
- return Sun(
51
- ra=ra.hours,
52
- dec=dec.degrees,
53
- name="Sun",
54
- dt=dt,
55
- apparent_size=apparent_diameter_degrees,
56
- geometry=circle((ra.hours, dec.degrees), apparent_diameter_degrees),
57
- )
58
-
59
-
60
13
  class Sun(SkyObject):
61
14
  """Sun model."""
62
15
 
63
- _manager = SunManager
64
-
65
16
  name: str = "Sun"
66
17
  """Name of the Sun"""
67
18
 
@@ -72,7 +23,7 @@ class Sun(SkyObject):
72
23
  """Apparent size (degrees)"""
73
24
 
74
25
  geometry: Polygon = None
75
- """Shapely Polygon of the Sun's extent. Right ascension coordinates are in 24H format."""
26
+ """Shapely Polygon of the Sun's extent. Right ascension coordinates are in degrees (0...360)."""
76
27
 
77
28
  def __init__(
78
29
  self,
@@ -91,6 +42,7 @@ class Sun(SkyObject):
91
42
 
92
43
  @classmethod
93
44
  def get(
45
+ cls,
94
46
  dt: datetime = None,
95
47
  lat: float = None,
96
48
  lon: float = None,
@@ -105,4 +57,31 @@ class Sun(SkyObject):
105
57
  lon: Longitude of observing location
106
58
  ephemeris: Ephemeris to use for calculating Sun/moon/planet positions (see [Skyfield's documentation](https://rhodesmill.org/skyfield/planets.html) for details)
107
59
  """
108
- pass
60
+ RADIUS_KM = 695_700
61
+
62
+ dt = dt_or_now(dt)
63
+ ephemeris = load(ephemeris)
64
+ timescale = load.timescale().from_datetime(dt)
65
+ earth, sun = ephemeris["earth"], ephemeris["sun"]
66
+
67
+ if lat is not None and lon is not None:
68
+ position = earth + wgs84.latlon(lat, lon)
69
+ astrometric = position.at(timescale).observe(sun)
70
+ apparent = astrometric.apparent()
71
+ ra, dec, distance = apparent.radec()
72
+ else:
73
+ astrometric = earth.at(timescale).observe(sun)
74
+ ra, dec, distance = astrometric.radec()
75
+
76
+ apparent_diameter_degrees = Angle(
77
+ radians=np.arcsin(RADIUS_KM / distance.km) * 2.0
78
+ ).degrees
79
+
80
+ return Sun(
81
+ ra=ra.hours * 15,
82
+ dec=dec.degrees,
83
+ name="Sun",
84
+ dt=dt,
85
+ apparent_size=apparent_diameter_degrees,
86
+ geometry=circle((ra.hours * 15, dec.degrees), apparent_diameter_degrees),
87
+ )
starplot/optic.py CHANGED
@@ -7,6 +7,7 @@ from cartopy import crs as ccrs
7
7
  from matplotlib import pyplot as plt, patches, path
8
8
  from skyfield.api import wgs84, Star as SkyfieldStar
9
9
 
10
+ from starplot.coordinates import CoordinateSystem
10
11
  from starplot import callables
11
12
  from starplot.base import BasePlot, DPI
12
13
  from starplot.data.stars import StarCatalog, STAR_NAMES
@@ -34,7 +35,7 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
34
35
 
35
36
  Args:
36
37
  optic: Optic instance that defines optical parameters
37
- ra: Right ascension of target center, in hours (0...24)
38
+ ra: Right ascension of target center, in degrees (0...360)
38
39
  dec: Declination of target center, in degrees (-90...90)
39
40
  lat: Latitude of observer's location
40
41
  lon: Longitude of observer's location
@@ -46,12 +47,15 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
46
47
  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
48
  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
49
  autoscale: If True, then the scale will be set automatically based on resolution.
50
+ suppress_warnings: If True (the default), then all warnings will be suppressed
49
51
 
50
52
  Returns:
51
53
  OpticPlot: A new instance of an OpticPlot
52
54
 
53
55
  """
54
56
 
57
+ _coordinate_system = CoordinateSystem.AZ_ALT
58
+
55
59
  FIELD_OF_VIEW_MAX = 9.0
56
60
 
57
61
  def __init__(
@@ -69,6 +73,7 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
69
73
  raise_on_below_horizon: bool = True,
70
74
  scale: float = 1.0,
71
75
  autoscale: bool = False,
76
+ suppress_warnings: bool = True,
72
77
  *args,
73
78
  **kwargs,
74
79
  ) -> "OpticPlot":
@@ -80,6 +85,7 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
80
85
  hide_colliding_labels,
81
86
  scale=scale,
82
87
  autoscale=autoscale,
88
+ suppress_warnings=suppress_warnings,
83
89
  *args,
84
90
  **kwargs,
85
91
  )
@@ -108,7 +114,7 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
108
114
 
109
115
  def _prepare_coords(self, ra, dec) -> (float, float):
110
116
  """Converts RA/DEC to AZ/ALT"""
111
- point = SkyfieldStar(ra_hours=ra, dec_degrees=dec)
117
+ point = SkyfieldStar(ra_hours=ra / 15, dec_degrees=dec)
112
118
  position = self.observe(point)
113
119
  pos_apparent = position.apparent()
114
120
  pos_alt, pos_az, _ = pos_apparent.altaz()
@@ -121,7 +127,7 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
121
127
  """Determine if a coordinate is within the bounds of the plot.
122
128
 
123
129
  Args:
124
- ra: Right ascension, in hours (0...24)
130
+ ra: Right ascension, in degrees (0...360)
125
131
  dec: Declination, in degrees (-90...90)
126
132
 
127
133
  Returns:
@@ -150,7 +156,7 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
150
156
  earth = self.ephemeris["earth"]
151
157
 
152
158
  self.location = earth + wgs84.latlon(self.lat, self.lon)
153
- self.star = SkyfieldStar(ra_hours=self.ra, dec_degrees=self.dec)
159
+ self.star = SkyfieldStar(ra_hours=self.ra / 15, dec_degrees=self.dec)
154
160
  self.observe = self.location.at(self.timescale).observe
155
161
  self.position = self.observe(self.star)
156
162
 
@@ -161,15 +167,15 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
161
167
  raise ValueError("Target is below horizon at specified time/location.")
162
168
 
163
169
  def _adjust_radec_minmax(self):
164
- self.ra_min = self.ra - self.optic.true_fov / 15 * 1.08
165
- self.ra_max = self.ra + self.optic.true_fov / 15 * 1.08
170
+ self.ra_min = self.ra - self.optic.true_fov * 10
171
+ self.ra_max = self.ra + self.optic.true_fov * 10
166
172
  self.dec_max = self.dec + self.optic.true_fov / 2 * 1.03
167
173
  self.dec_min = self.dec - self.optic.true_fov / 2 * 1.03
168
174
 
169
175
  if self.dec > 70 or self.dec < -70:
170
176
  # naive method of getting all the stars near the poles
171
177
  self.ra_min = 0
172
- self.ra_max = 24
178
+ self.ra_max = 360
173
179
 
174
180
  self.logger.debug(
175
181
  f"Extent = RA ({self.ra_min:.2f}, {self.ra_max:.2f}) DEC ({self.dec_min:.2f}, {self.dec_max:.2f})"
@@ -202,15 +208,14 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
202
208
  @use_style(ObjectStyle, "star")
203
209
  def stars(
204
210
  self,
205
- mag: float = 6.0,
211
+ where: list = None,
212
+ where_labels: list = None,
206
213
  catalog: StarCatalog = StarCatalog.BIG_SKY_MAG11,
207
214
  style: ObjectStyle = None,
208
215
  rasterize: bool = False,
209
216
  size_fn: Callable[[Star], float] = callables.size_by_magnitude_for_optic,
210
217
  alpha_fn: Callable[[Star], float] = callables.alpha_by_magnitude,
211
218
  color_fn: Callable[[Star], str] = None,
212
- where: list = None,
213
- where_labels: list = None,
214
219
  labels: Mapping[int, str] = STAR_NAMES,
215
220
  legend_label: str = "Star",
216
221
  bayer_labels: bool = False,
@@ -222,15 +227,14 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
222
227
  Plots stars
223
228
 
224
229
  Args:
225
- mag: Limiting magnitude of stars to plot
230
+ where: A list of expressions that determine which stars to plot. See [Selecting Objects](/reference-selecting-objects/) for details.
231
+ where_labels: A list of expressions that determine which stars are labeled on the plot. See [Selecting Objects](/reference-selecting-objects/) for details.
226
232
  catalog: The catalog of stars to use
227
233
  style: If `None`, then the plot's style for stars will be used
228
234
  rasterize: If True, then the stars will be rasterized when plotted, which can speed up exporting to SVG and reduce the file size but with a loss of image quality
229
235
  size_fn: Callable for calculating the marker size of each star. If `None`, then the marker style's size will be used.
230
236
  alpha_fn: Callable for calculating the alpha value (aka "opacity") of each star. If `None`, then the marker style's alpha will be used.
231
237
  color_fn: Callable for calculating the color of each star. If `None`, then the marker style's color will be used.
232
- where: A list of expressions that determine which stars to plot. See [Selecting Objects](/reference-selecting-objects/) for details.
233
- where_labels: A list of expressions that determine which stars are labeled on the plot. See [Selecting Objects](/reference-selecting-objects/) for details.
234
238
  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`.
235
239
  legend_label: Label for stars in the legend. If `None`, then they will not be in the legend.
236
240
  bayer_labels: If True, then Bayer labels for stars will be plotted.
@@ -242,10 +246,9 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
242
246
  if size_fn is not None:
243
247
 
244
248
  def size_fn_mx(s):
245
- return size_fn(s) * optic_star_multiplier
249
+ return size_fn(s) * optic_star_multiplier * 0.68
246
250
 
247
251
  super().stars(
248
- mag=mag,
249
252
  catalog=catalog,
250
253
  style=style,
251
254
  rasterize=rasterize,
@@ -292,7 +295,7 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
292
295
  ]
293
296
  values = [
294
297
  f"{self.pos_alt.degrees:.0f}\N{DEGREE SIGN} / {self.pos_az.degrees:.0f}\N{DEGREE SIGN} ({azimuth_to_string(self.pos_az.degrees)})",
295
- f"{self.ra:.2f}h / {self.dec:.2f}\N{DEGREE SIGN}",
298
+ f"{(self.ra / 15):.2f}h / {self.dec:.2f}\N{DEGREE SIGN}",
296
299
  f"{self.lat:.2f}\N{DEGREE SIGN}, {self.lon:.2f}\N{DEGREE SIGN}",
297
300
  dt_str,
298
301
  str(self.optic),
@@ -336,6 +339,7 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
336
339
  zorder=ZOrderEnum.LAYER_1,
337
340
  )
338
341
  self.ax.add_patch(self._background_clip_path)
342
+ self._update_clip_path_polygon()
339
343
 
340
344
  # Inner Border
341
345
  inner_border = self.optic.patch(
@@ -384,9 +388,8 @@ class OpticPlot(BasePlot, ExtentMaskMixin, StarPlotterMixin, DsoPlotterMixin):
384
388
  self.ax.yaxis.set_visible(False)
385
389
  self.ax.axis("off")
386
390
 
387
- self._plot_border()
388
391
  self._fit_to_ax()
389
-
390
392
  self.ax.set_xlim(-1.06 * self.optic.xlim, 1.06 * self.optic.xlim)
391
393
  self.ax.set_ylim(-1.06 * self.optic.ylim, 1.06 * self.optic.ylim)
392
394
  self.optic.transform(self.ax)
395
+ self._plot_border()
@@ -1,2 +1,4 @@
1
+ from .constellations import ConstellationPlotterMixin # noqa: F401
1
2
  from .stars import StarPlotterMixin # noqa: F401
2
3
  from .dsos import DsoPlotterMixin # noqa: F401
4
+ from .milkyway import MilkyWayPlotterMixin # noqa: F401