starplot 0.15.8__py2.py3-none-any.whl → 0.16.1__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 (43) hide show
  1. starplot/__init__.py +7 -2
  2. starplot/base.py +57 -60
  3. starplot/cli.py +3 -3
  4. starplot/config.py +56 -0
  5. starplot/data/__init__.py +5 -5
  6. starplot/data/bigsky.py +3 -3
  7. starplot/data/db.py +2 -2
  8. starplot/data/library/sky.db +0 -0
  9. starplot/geometry.py +48 -0
  10. starplot/horizon.py +194 -90
  11. starplot/map.py +71 -168
  12. starplot/mixins.py +0 -55
  13. starplot/models/dso.py +10 -2
  14. starplot/observer.py +71 -0
  15. starplot/optic.py +61 -26
  16. starplot/plotters/__init__.py +2 -0
  17. starplot/plotters/constellations.py +4 -6
  18. starplot/plotters/dsos.py +3 -2
  19. starplot/plotters/gradients.py +153 -0
  20. starplot/plotters/legend.py +247 -0
  21. starplot/plotters/milkyway.py +8 -5
  22. starplot/plotters/stars.py +5 -3
  23. starplot/projections.py +155 -55
  24. starplot/styles/base.py +98 -22
  25. starplot/styles/ext/antique.yml +0 -1
  26. starplot/styles/ext/blue_dark.yml +0 -1
  27. starplot/styles/ext/blue_gold.yml +60 -52
  28. starplot/styles/ext/blue_light.yml +0 -1
  29. starplot/styles/ext/blue_medium.yml +7 -7
  30. starplot/styles/ext/blue_night.yml +178 -0
  31. starplot/styles/ext/cb_wong.yml +0 -1
  32. starplot/styles/ext/gradient_presets.yml +158 -0
  33. starplot/styles/ext/grayscale.yml +0 -1
  34. starplot/styles/ext/grayscale_dark.yml +0 -1
  35. starplot/styles/ext/nord.yml +0 -1
  36. starplot/styles/extensions.py +90 -0
  37. starplot/zenith.py +174 -0
  38. {starplot-0.15.8.dist-info → starplot-0.16.1.dist-info}/METADATA +18 -11
  39. {starplot-0.15.8.dist-info → starplot-0.16.1.dist-info}/RECORD +42 -36
  40. starplot/settings.py +0 -26
  41. {starplot-0.15.8.dist-info → starplot-0.16.1.dist-info}/WHEEL +0 -0
  42. {starplot-0.15.8.dist-info → starplot-0.16.1.dist-info}/entry_points.txt +0 -0
  43. {starplot-0.15.8.dist-info → starplot-0.16.1.dist-info}/licenses/LICENSE +0 -0
@@ -232,9 +232,11 @@ class StarPlotterMixin:
232
232
 
233
233
  if getattr(self, "projection", None) == "zenith":
234
234
  # filter stars for zenith plots to only include those above horizon
235
- self.location = self.earth + wgs84.latlon(self.lat, self.lon)
235
+ self.location = self.earth + wgs84.latlon(
236
+ self.observer.lat, self.observer.lon
237
+ )
236
238
  stars_apparent = (
237
- self.location.at(self.timescale)
239
+ self.location.at(self.observer.timescale)
238
240
  .observe(SkyfieldStar.from_dataframe(stars_df))
239
241
  .apparent()
240
242
  )
@@ -244,7 +246,7 @@ class StarPlotterMixin:
244
246
  stars_df = stars_df[stars_df["alt"] > 0]
245
247
  else:
246
248
  nearby_stars = SkyfieldStar.from_dataframe(stars_df)
247
- astrometric = self.earth.at(self.timescale).observe(nearby_stars)
249
+ astrometric = self.earth.at(self.observer.timescale).observe(nearby_stars)
248
250
  stars_ra, stars_dec, _ = astrometric.radec()
249
251
  stars_df["ra"], stars_df["dec"] = (
250
252
  stars_ra.hours * 15,
starplot/projections.py CHANGED
@@ -1,78 +1,178 @@
1
- from enum import Enum
1
+ from abc import ABC
2
+ from functools import cached_property
2
3
 
3
4
  from cartopy import crs as ccrs
5
+ from pydantic import BaseModel, Field
4
6
 
5
7
 
6
- class Projection(str, Enum):
7
- """Supported projections for MapPlots"""
8
+ class CenterRA(BaseModel, ABC):
9
+ center_ra: float = Field(default=180, ge=0, le=360)
10
+ """Central right ascension"""
8
11
 
9
- STEREO_NORTH = "stereo_north"
10
- """Good for objects near the north celestial pole, but distorts objects near the mid declinations"""
11
12
 
12
- STEREO_SOUTH = "stereo_south"
13
- """Good for objects near the south celestial pole, but distorts objects near the mid declinations"""
13
+ class CenterDEC(BaseModel, ABC):
14
+ center_dec: float = Field(default=0, ge=-90, le=90)
15
+ """Central declination"""
14
16
 
15
- MERCATOR = "mercator"
16
- """Good for declinations between -70 and 70, but distorts objects near the poles"""
17
17
 
18
- MOLLWEIDE = "mollweide"
19
- """Good for showing the entire celestial sphere in one plot"""
18
+ class CenterRADEC(CenterRA, CenterDEC):
19
+ pass
20
20
 
21
- MILLER = "miller"
22
- """Similar to Mercator: good for declinations between -70 and 70, but distorts objects near the poles"""
23
21
 
24
- ORTHOGRAPHIC = "orthographic"
22
+ class Azimuth(BaseModel, ABC):
23
+ azimuth: float = Field(default=0, ge=0, le=360)
24
+ """Direction of central line of the projection"""
25
+
26
+
27
+ class ProjectionBase(BaseModel, ABC):
28
+ threshold: int = 1000
29
+
30
+ _ccrs = None
31
+
32
+ class Config:
33
+ arbitrary_types_allowed = True
34
+
35
+ @cached_property
36
+ def crs(self):
37
+ kwargs = {}
38
+
39
+ if hasattr(self, "center_ra"):
40
+ kwargs["central_longitude"] = -1 * self.center_ra
41
+
42
+ if hasattr(self, "center_dec"):
43
+ kwargs["central_latitude"] = self.center_dec
44
+
45
+ if hasattr(self, "azimuth"):
46
+ kwargs["azimuth"] = self.azimuth
47
+
48
+ c = self._ccrs(**kwargs)
49
+ c.threshold = self.threshold
50
+ return c
51
+
52
+
53
+ class AutoProjection:
25
54
  """
26
- Shows the celestial sphere as a 3D-looking globe. Objects near the edges will be distorted.
55
+ Automatically selects a projection based on the RA/DEC extent you specify when creating the map plot.
56
+
57
+ This uses a pretty simple method:
58
+
59
+ 1. If the extent is the full celestial sphere (RA is 0 to 360 and DEC is -90 to 90), then it'll use Mollweide
27
60
 
28
- **This is a _perspective_ projection, so it requires the following `kwargs` when creating the plot: `lat`, `lon`, and `dt`**. _The perspective of the globe will be based on these values._
61
+ 2. If the max declination is greater than 75 and the min is greater than or equal to 0, then it'll use a Stereographic North projection
62
+
63
+ 3. If the max declination is less than or equal to 0 and the min is less than -75, then it'll use a Stereographic South projection
64
+
65
+ 4. If the extent doesn't match any of the above, then it'll use a Miller projection
66
+
67
+ In all cases, it sets the central RA to the midpoint of the RA extent.
68
+
69
+ Unlike the other projection options, this class does not expose any public parameters (e.g. center RA/DEC), since everything is determined automatically.
70
+
71
+ To use this automatic projection:
72
+
73
+ ```python
74
+
75
+ from starplot import MapPlot, AutoProjection
76
+
77
+ p = MapPlot(
78
+ projection=AutoProjection(),
79
+ ra_min=4 * 15,
80
+ ra_max=6 * 15,
81
+ dec_min=0,
82
+ dec_max=20,
83
+ )
84
+ ```
29
85
  """
30
86
 
31
- ROBINSON = "robinson"
87
+ def _is_global(
88
+ self, ra_min: float, ra_max: float, dec_min: float, dec_max: float
89
+ ) -> bool:
90
+ return ra_min == 0 and ra_max == 360 and dec_min == -90 and dec_max == 90
91
+
92
+ def crs(self, ra_min: float, ra_max: float, dec_min: float, dec_max: float):
93
+ central_longitude = -1 * (ra_min + ra_max) / 2
94
+
95
+ if self._is_global(ra_min, ra_max, dec_min, dec_max):
96
+ c = ccrs.Mollweide(central_longitude=central_longitude)
97
+
98
+ elif dec_max < 75 and dec_min > -75:
99
+ c = ccrs.Miller(central_longitude=central_longitude)
100
+
101
+ elif dec_max > 75 and dec_min >= 0:
102
+ c = ccrs.NorthPolarStereo(central_longitude=central_longitude)
103
+
104
+ elif dec_max <= 0 and dec_min < -75:
105
+ c = ccrs.SouthPolarStereo(central_longitude=central_longitude)
106
+
107
+ else:
108
+ c = ccrs.Miller(central_longitude=central_longitude)
109
+
110
+ c.threshold = 1_000
111
+
112
+ return c
113
+
114
+
115
+ class Miller(ProjectionBase, CenterRA):
116
+ """Similar to Mercator: good for declinations between -70 and 70, but distorts objects near the poles"""
117
+
118
+ _ccrs = ccrs.Miller
119
+
120
+
121
+ class Mercator(ProjectionBase, CenterRA):
122
+ """Good for declinations between -70 and 70, but distorts objects near the poles"""
123
+
124
+ _ccrs = ccrs.Mercator
125
+
126
+
127
+ class ObliqueMercator(ProjectionBase, CenterRADEC, Azimuth):
128
+ """Oblique Mercator projection"""
129
+
130
+ _ccrs = ccrs.ObliqueMercator
131
+
132
+
133
+ class Mollweide(ProjectionBase, CenterRA):
32
134
  """Good for showing the entire celestial sphere in one plot"""
33
135
 
34
- LAMBERT_AZ_EQ_AREA = "lambert_az_eq_area"
136
+ _ccrs = ccrs.Mollweide
137
+
138
+
139
+ class Equidistant(ProjectionBase, CenterRADEC):
140
+ """Shows accurate distances from the center position. Often used for planispheres."""
141
+
142
+ _ccrs = ccrs.AzimuthalEquidistant
143
+
144
+
145
+ class StereoNorth(ProjectionBase, CenterRA):
146
+ """Good for objects near the north celestial pole, but distorts objects near the mid declinations"""
147
+
148
+ _ccrs = ccrs.NorthPolarStereo
149
+
150
+
151
+ class StereoSouth(ProjectionBase, CenterRA):
152
+ """Good for objects near the south celestial pole, but distorts objects near the mid declinations"""
153
+
154
+ _ccrs = ccrs.SouthPolarStereo
155
+
156
+
157
+ class Robinson(ProjectionBase, CenterRA):
158
+ """Good for showing the entire celestial sphere in one plot"""
159
+
160
+ _ccrs = ccrs.Robinson
161
+
162
+
163
+ class LambertAzEqArea(ProjectionBase, CenterRADEC):
35
164
  """Lambert Azimuthal Equal-Area projection - accurately shows area, but distorts angles."""
36
165
 
37
- STEREOGRAPHIC = "stereographic"
38
- """
39
- Similar to the North/South Stereographic projection, but this version is location-dependent.
166
+ _ccrs = ccrs.LambertAzimuthalEqualArea
40
167
 
41
- **This is a _perspective_ projection, so it requires the following `kwargs` when creating the plot: `lat`, `lon`, and `dt`**. _The perspective of the map will be based on these values._
42
- """
43
168
 
44
- ZENITH = "zenith"
45
- """
46
- **This is a _perspective_ projection, so it requires the following `kwargs` when creating the plot: `lat`, `lon`, and `dt`**. _The perspective of the map will be based on these values._
169
+ class Orthographic(ProjectionBase, CenterRADEC):
170
+ """Shows the celestial sphere as a 3D-looking globe. Objects near the edges will be distorted."""
47
171
 
48
- The Zenith projection shows the whole sky as seen from a specific time and place. They're also sometimes called "star charts" but that name is used for many different types of star maps, so Starplot uses the more specific name "Zenith plot" (which reflects the fact that the [zenith](https://en.wikipedia.org/wiki/Zenith) is in the center of the chart).
49
- """
172
+ _ccrs = ccrs.Orthographic
50
173
 
51
- @staticmethod
52
- def crs(projection, center_lon=-180, **kwargs):
53
- projections = {
54
- Projection.STEREO_NORTH: ccrs.NorthPolarStereo,
55
- Projection.STEREO_SOUTH: ccrs.SouthPolarStereo,
56
- Projection.LAMBERT_AZ_EQ_AREA: ccrs.LambertAzimuthalEqualArea,
57
- Projection.MERCATOR: ccrs.Mercator,
58
- Projection.MOLLWEIDE: ccrs.Mollweide,
59
- Projection.MILLER: ccrs.Miller,
60
- Projection.ORTHOGRAPHIC: ccrs.Orthographic,
61
- Projection.ROBINSON: ccrs.Robinson,
62
- Projection.STEREOGRAPHIC: ccrs.Stereographic,
63
- Projection.ZENITH: ccrs.Stereographic,
64
- }
65
- proj_class = projections.get(projection)
66
- if projection in [
67
- Projection.ORTHOGRAPHIC,
68
- Projection.STEREOGRAPHIC,
69
- Projection.ZENITH,
70
- ]:
71
- return proj_class(
72
- central_longitude=kwargs["lon"], central_latitude=kwargs["lat"]
73
- )
74
- else:
75
- if kwargs.get("center_lat") is not None:
76
- kwargs["central_latitude"] = kwargs.pop("center_lat")
77
174
 
78
- return proj_class(center_lon, **kwargs)
175
+ class Stereographic(ProjectionBase, CenterRADEC):
176
+ """Similar to the North/South Stereographic projection, but allows custom central declination"""
177
+
178
+ _ccrs = ccrs.Stereographic
starplot/styles/base.py CHANGED
@@ -47,6 +47,21 @@ class BaseStyle(BaseModel):
47
47
  use_enum_values = True
48
48
  validate_assignment = True
49
49
 
50
+ def __enter__(self):
51
+ self._original = self.model_copy(deep=True)
52
+ return self
53
+
54
+ def __exit__(self, exception_type, exception_value, traceback):
55
+ for field_name in self.__pydantic_fields__.keys():
56
+ original_value = getattr(self._original, field_name)
57
+ setattr(self, field_name, original_value)
58
+
59
+
60
+ class GradientDirection(str, Enum):
61
+ LINEAR = "linear"
62
+ RADIAL = "radial"
63
+ MOLLWEIDE = "mollweide"
64
+
50
65
 
51
66
  class FillStyleEnum(str, Enum):
52
67
  """Constants that represent the possible fill styles for markers."""
@@ -197,8 +212,14 @@ class LegendLocationEnum(str, Enum):
197
212
  INSIDE_BOTTOM = "lower center"
198
213
  INSIDE_BOTTOM_RIGHT = "lower right"
199
214
  INSIDE_BOTTOM_LEFT = "lower left"
200
- OUTSIDE_TOP = "outside upper center"
201
- OUTSIDE_BOTTOM = "outside lower center"
215
+
216
+ # OUTSIDE_TOP = "outside upper center"
217
+ # OUTSIDE_BOTTOM = "outside lower center"
218
+
219
+ OUTSIDE_TOP_LEFT = "outside left upper"
220
+ OUTSIDE_TOP_RIGHT = "outside right upper"
221
+ OUTSIDE_BOTTOM_RIGHT = "outside right lower"
222
+ OUTSIDE_BOTTOM_LEFT = "outside left lower"
202
223
 
203
224
 
204
225
  class AnchorPointEnum(str, Enum):
@@ -253,6 +274,14 @@ class AnchorPointEnum(str, Enum):
253
274
  return options.get(value)
254
275
 
255
276
 
277
+ class AlignmentEnum(str, Enum):
278
+ """Alignment options for the legend's title and entries"""
279
+
280
+ LEFT = "left"
281
+ RIGHT = "right"
282
+ CENTER = "center"
283
+
284
+
256
285
  class ZOrderEnum(int, Enum):
257
286
  """
258
287
  Z Order presets for managing layers
@@ -605,7 +634,10 @@ class PathStyle(BaseStyle):
605
634
  class LegendStyle(BaseStyle):
606
635
  """Defines the style for the map legend. *Only applies to map plots.*"""
607
636
 
608
- location: LegendLocationEnum = LegendLocationEnum.OUTSIDE_BOTTOM
637
+ alignment: AlignmentEnum = AlignmentEnum.LEFT
638
+ """Alignment for the legend's title and entries"""
639
+
640
+ location: LegendLocationEnum = LegendLocationEnum.INSIDE_BOTTOM_RIGHT
609
641
  """Location of the legend, relative to the map area (inside or outside)"""
610
642
 
611
643
  background_color: ColorStr = ColorStr("#fff")
@@ -614,6 +646,15 @@ class LegendStyle(BaseStyle):
614
646
  background_alpha: float = 1.0
615
647
  """Background's alpha (transparency)"""
616
648
 
649
+ padding: float = 0
650
+ """Padding on the outside of the legend. Negative numbers are supported."""
651
+
652
+ padding_x: float = 0
653
+ """Padding (in pixels) between the _outside_ of the legend and the map in the X axis. Negative numbers are supported."""
654
+
655
+ padding_y: float = 0
656
+ """Padding (in pixels) between the _outside_ of the legend and the map in the Y axis. Negative numbers are supported."""
657
+
617
658
  expand: bool = False
618
659
  """If True, the legend will be expanded to fit the full width of the map"""
619
660
 
@@ -629,8 +670,11 @@ class LegendStyle(BaseStyle):
629
670
  symbol_padding: float = 0.2
630
671
  """Padding between each symbol and its label"""
631
672
 
673
+ border_color: ColorStr = ColorStr("#c5c5c5")
674
+ """Border color of the legend box"""
675
+
632
676
  border_padding: float = 1.28
633
- """Padding around legend border"""
677
+ """Padding between legend entries and the legend border"""
634
678
 
635
679
  font_size: int = 23
636
680
  """Font size of the legend labels, in points"""
@@ -638,6 +682,15 @@ class LegendStyle(BaseStyle):
638
682
  font_color: ColorStr = ColorStr("#000")
639
683
  """Font color for legend labels"""
640
684
 
685
+ title_font_size: int = 36
686
+ """Font size of the legend title"""
687
+
688
+ title_font_weight: FontWeightEnum = FontWeightEnum.HEAVY
689
+ """Font weight of the legend title"""
690
+
691
+ title_font_name: str = "Inter"
692
+ """Name of the font to use for the title. Comma-separated list."""
693
+
641
694
  zorder: int = ZOrderEnum.LAYER_5
642
695
  """Zorder of the legend"""
643
696
 
@@ -653,6 +706,14 @@ class LegendStyle(BaseStyle):
653
706
  handletextpad=self.symbol_padding,
654
707
  mode="expand" if self.expand else None,
655
708
  facecolor=self.background_color.as_hex(),
709
+ title_fontproperties=dict(
710
+ weight=self.title_font_weight,
711
+ size=self.title_font_size,
712
+ family=self.title_font_name.split(","),
713
+ ),
714
+ alignment=self.alignment,
715
+ edgecolor=self.border_color.as_hex(),
716
+ borderaxespad=self.padding,
656
717
  )
657
718
 
658
719
 
@@ -661,8 +722,28 @@ class PlotStyle(BaseStyle):
661
722
  Defines the styling for a plot
662
723
  """
663
724
 
664
- background_color: ColorStr = ColorStr("#fff")
665
- """Background color of the map region"""
725
+ background_color: list[tuple[float, str]] | ColorStr = ColorStr("#fff")
726
+ """
727
+ Background color of the map region.
728
+
729
+ This can either be a single color (e.g. `#7abfff`) or a list that defines a gradient.
730
+
731
+ For gradients, the list items should be tuples with two elements: a float that defines
732
+ the stop and a string that defines the color for that stop. For example:
733
+
734
+ ```
735
+ "background_color": [
736
+ (0.0, "#7abfff"),
737
+ (0.2, "#7abfff"),
738
+ (0.9, "#568feb"),
739
+ (1.0, "#3f7ee3"), # the last stop should always be at 1.0
740
+ ]
741
+ ```
742
+
743
+ There are a few predefined gradients available as [style extensions](/reference-styling/#style-extensions).
744
+
745
+ **Gradient backgrounds are not yet supported for optic plots that use a camera.**
746
+ """
666
747
 
667
748
  figure_background_color: ColorStr = ColorStr("#fff")
668
749
 
@@ -692,10 +773,10 @@ class PlotStyle(BaseStyle):
692
773
 
693
774
  # Title
694
775
  title: LabelStyle = LabelStyle(
695
- font_size=20,
776
+ font_size=70,
696
777
  font_weight=FontWeightEnum.BOLD,
697
778
  zorder=ZOrderEnum.LAYER_5,
698
- line_spacing=48,
779
+ line_spacing=150,
699
780
  anchor_point=AnchorPointEnum.BOTTOM_CENTER,
700
781
  )
701
782
  """Styling for info text (only applies to zenith and optic plots)"""
@@ -890,17 +971,6 @@ class PlotStyle(BaseStyle):
890
971
  )
891
972
  """Styling for dark nebulas"""
892
973
 
893
- dso_hii_ionized_region: ObjectStyle = ObjectStyle(
894
- marker=MarkerStyle(
895
- symbol=MarkerSymbolEnum.SQUARE,
896
- fill=FillStyleEnum.TOP,
897
- color="#000",
898
- zorder=ZOrderEnum.LAYER_3 - 1,
899
- ),
900
- label=LabelStyle(),
901
- )
902
- """Styling for HII Ionized regions"""
903
-
904
974
  dso_supernova_remnant: ObjectStyle = ObjectStyle(
905
975
  marker=MarkerStyle(
906
976
  symbol=MarkerSymbolEnum.SQUARE,
@@ -956,7 +1026,9 @@ class PlotStyle(BaseStyle):
956
1026
  )
957
1027
  """Styling for 'duplicate record' (as designated by OpenNGC) types of deep sky objects"""
958
1028
 
959
- constellation_lines: LineStyle = LineStyle(color="#c8c8c8")
1029
+ constellation_lines: LineStyle = LineStyle(
1030
+ color="#c8c8c8", zorder=ZOrderEnum.LAYER_3
1031
+ )
960
1032
  """Styling for constellation lines"""
961
1033
 
962
1034
  constellation_borders: LineStyle = LineStyle(
@@ -999,10 +1071,11 @@ class PlotStyle(BaseStyle):
999
1071
  zorder=ZOrderEnum.LAYER_2,
1000
1072
  ),
1001
1073
  label=LabelStyle(
1002
- font_size=20,
1074
+ font_size=24,
1003
1075
  font_color="#000",
1004
1076
  font_alpha=1,
1005
1077
  anchor_point=AnchorPointEnum.BOTTOM_CENTER,
1078
+ zorder=ZOrderEnum.LAYER_5 + 1000,
1006
1079
  ),
1007
1080
  )
1008
1081
  """Styling for gridlines (including Right Ascension / Declination labels). *Only applies to map plots*."""
@@ -1095,13 +1168,13 @@ class PlotStyle(BaseStyle):
1095
1168
  DsoType.EMISSION_NEBULA: self.dso_nebula,
1096
1169
  DsoType.STAR_CLUSTER_NEBULA: self.dso_nebula,
1097
1170
  DsoType.REFLECTION_NEBULA: self.dso_nebula,
1171
+ DsoType.HII_IONIZED_REGION: self.dso_nebula,
1098
1172
  # Stars ----------
1099
1173
  DsoType.STAR: self.star,
1100
1174
  DsoType.DOUBLE_STAR: self.dso_double_star,
1101
1175
  DsoType.ASSOCIATION_OF_STARS: self.dso_association_stars,
1102
1176
  # Others ----------
1103
1177
  DsoType.DARK_NEBULA: self.dso_dark_nebula,
1104
- DsoType.HII_IONIZED_REGION: self.dso_hii_ionized_region,
1105
1178
  DsoType.SUPERNOVA_REMNANT: self.dso_supernova_remnant,
1106
1179
  DsoType.NOVA_STAR: self.dso_nova_star,
1107
1180
  DsoType.NONEXISTENT: self.dso_nonexistant,
@@ -1176,3 +1249,6 @@ class PlotStyle(BaseStyle):
1176
1249
  raise TypeError("Style overrides must be dictionary types.")
1177
1250
  merge_dict(style_dict, a)
1178
1251
  return PlotStyle.parse_obj(style_dict)
1252
+
1253
+ def has_gradient_background(self):
1254
+ return isinstance(self.background_color, list)
@@ -163,7 +163,6 @@ dso_unknown: &DSO
163
163
  label:
164
164
  font_color: hsl(71, 58%, 36%)
165
165
  dso_dark_nebula: *DSO
166
- dso_hii_ionized_region: *DSO
167
166
  dso_supernova_remnant: *DSO
168
167
  dso_nova_star: *DSO
169
168
  dso_nonexistant: *DSO
@@ -105,7 +105,6 @@ dso_unknown: &DSO
105
105
  edge_color: hsl(209, 50%, 20%)
106
106
  zorder: -500
107
107
  dso_dark_nebula: *DSO
108
- dso_hii_ionized_region: *DSO
109
108
  dso_supernova_remnant: *DSO
110
109
  dso_nova_star: *DSO
111
110
  dso_nonexistant: *DSO
@@ -1,16 +1,50 @@
1
1
  # blue_gold
2
-
3
2
  background_color: rgb(46, 61, 74)
4
- figure_background_color: '#fff'
3
+ figure_background_color: hsl(208, 23%, 13%)
5
4
 
6
5
  text_border_color: rgb(46, 61, 74)
7
6
 
8
- border_bg_color: hsl(212, 27%, 56%)
7
+ border_bg_color: hsl(212, 27%, 8%)
9
8
  border_font_color: '#f1f6ff'
10
9
  border_line_color: '#2f4358'
11
10
 
12
11
  title:
13
12
  font_color: '#f1f6ff'
13
+
14
+ legend:
15
+ background_color: 'rgb(46, 61, 74)'
16
+ font_color: 'rgb(244, 233, 203)'
17
+
18
+ celestial_equator:
19
+ label:
20
+ font_color: '#2d5ec2'
21
+ line:
22
+ color: hsl(220, 62%, 47%)
23
+ alpha: 0.8
24
+ ecliptic:
25
+ label:
26
+ font_color: hsl(4, 60%, 54%)
27
+ line:
28
+ color: hsl(4, 60%, 54%)
29
+ alpha: 0.9
30
+
31
+ horizon:
32
+ line:
33
+ color: hsl(208, 23%, 13%)
34
+ edge_color: hsl(208, 23%, 14%)
35
+ label:
36
+ font_color: hsl(208, 23%, 84%)
37
+
38
+ gridlines:
39
+ label:
40
+ font_alpha: 1
41
+ font_color: hsl(208, 23%, 84%)
42
+ line:
43
+ alpha: 0.6
44
+ color: '#888'
45
+ style: solid
46
+
47
+ # Stars
14
48
  star:
15
49
  marker:
16
50
  color: rgb(244, 233, 203)
@@ -33,20 +67,13 @@ constellation_lines:
33
67
  constellation_borders:
34
68
  color: hsl(208, 23%, 2%)
35
69
 
70
+ # Milky Way
71
+ milky_way:
72
+ alpha: 0.14
73
+ fill_color: '#94c5e3'
74
+ edge_width: 0
36
75
 
37
- celestial_equator:
38
- label:
39
- font_color: '#2d5ec2'
40
- line:
41
- color: hsl(220, 62%, 47%)
42
- alpha: 0.8
43
- ecliptic:
44
- label:
45
- font_color: hsl(4, 60%, 54%)
46
- line:
47
- color: hsl(4, 60%, 54%)
48
- alpha: 0.9
49
-
76
+ # Solar System
50
77
  planets:
51
78
  label:
52
79
  font_color: hsl(284, 78%, 90%)
@@ -54,58 +81,45 @@ planets:
54
81
  alpha: 1
55
82
  color: hsl(284, 80%, 80%)
56
83
  fill: full
57
- milky_way:
58
- alpha: 0.14
59
- fill_color: '#94c5e3'
60
- edge_width: 0
61
- gridlines:
62
- label:
63
- font_alpha: 1
64
- font_color: '#f1f6ff'
65
- line:
66
- alpha: 0.6
67
- color: '#888'
68
- style: solid
69
84
  sun:
70
85
  marker:
71
86
  color: '#ffd22e'
72
87
  edge_color: 'hsl(47, 100%, 29%)'
73
88
 
74
- horizon:
75
- line:
76
- color: hsl(208, 23%, 14%)
77
- edge_color: hsl(208, 23%, 14%)
78
- label:
79
- font_color: hsl(208, 23%, 84%)
80
-
81
-
82
89
  # DSOs
83
-
84
90
  dso_galaxy:
85
91
  marker:
86
92
  alpha: 1
87
- color: hsl(328, 23%, 54%)
88
- edge_color: hsl(328, 23%, 24%)
93
+ color: hsl(328, 30%, 56%)
94
+ edge_color: hsl(328, 63%, 24%)
89
95
  label:
90
- font_color: hsl(328, 23%, 54%)
96
+ font_color: hsl(328, 30%, 56%)
91
97
 
92
98
  dso_nebula: &DSO-NEB
93
99
  marker:
94
100
  alpha: 1
95
101
  color: hsl(118, 23%, 54%)
96
- edge_color: hsl(118, 23%, 24%)
102
+ edge_color: hsl(118, 23%, 20%)
97
103
  label:
98
104
  font_color: hsl(118, 23%, 54%)
99
- dso_planetary_nebula: *DSO-NEB
100
105
 
106
+ dso_planetary_nebula:
107
+ marker:
108
+ alpha: 1
109
+ color: hsl(118, 23%, 54%)
110
+ edge_color: hsl(118, 43%, 70%)
111
+ label:
112
+ font_color: hsl(118, 23%, 54%)
101
113
 
102
114
  dso_open_cluster: &DSO-OC
103
115
  marker:
104
116
  alpha: 1
105
- color: hsl(44deg 70% 64%)
106
- edge_color: rgb(46, 61, 74)
117
+ color: hsl(44, 70%, 64%)
118
+ edge_color: hsl(44, 98%, 63%)
119
+ # rgb(46, 61, 74)
120
+ edge_width: 1
107
121
  label:
108
- font_color: hsl(44deg 70% 64%)
122
+ font_color: hsl(44, 70%, 64%)
109
123
  dso_association_stars: *DSO-OC
110
124
 
111
125
  dso_globular_cluster:
@@ -114,10 +128,8 @@ dso_globular_cluster:
114
128
  color: hsl(44deg 70% 64%)
115
129
  edge_color: rgb(46, 61, 74)
116
130
  label:
117
- font_color: '#989400'
118
-
131
+ font_color: hsl(44, 70%, 64%)
119
132
 
120
- # other DSOs
121
133
  dso_unknown: &DSO
122
134
  marker:
123
135
  alpha: 1
@@ -126,12 +138,8 @@ dso_unknown: &DSO
126
138
  label:
127
139
  font_color: hsl(91, 53%, 40%)
128
140
  dso_dark_nebula: *DSO
129
- dso_hii_ionized_region: *DSO
130
141
  dso_supernova_remnant: *DSO
131
142
  dso_nova_star: *DSO
132
143
  dso_nonexistant: *DSO
133
144
  dso_unknown: *DSO
134
145
  dso_duplicate: *DSO
135
-
136
- legend:
137
- background_color: '#f1f6ff'
@@ -95,7 +95,6 @@ dso_unknown: &DSO
95
95
  label:
96
96
  font_color: hsl(91, 53%, 40%)
97
97
  dso_dark_nebula: *DSO
98
- dso_hii_ionized_region: *DSO
99
98
  dso_supernova_remnant: *DSO
100
99
  dso_nova_star: *DSO
101
100
  dso_nonexistant: *DSO