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.
- starplot/__init__.py +7 -2
- starplot/base.py +57 -60
- starplot/cli.py +3 -3
- starplot/config.py +56 -0
- starplot/data/__init__.py +5 -5
- starplot/data/bigsky.py +3 -3
- starplot/data/db.py +2 -2
- starplot/data/library/sky.db +0 -0
- starplot/geometry.py +48 -0
- starplot/horizon.py +194 -90
- starplot/map.py +71 -168
- starplot/mixins.py +0 -55
- starplot/models/dso.py +10 -2
- starplot/observer.py +71 -0
- starplot/optic.py +61 -26
- starplot/plotters/__init__.py +2 -0
- starplot/plotters/constellations.py +4 -6
- starplot/plotters/dsos.py +3 -2
- starplot/plotters/gradients.py +153 -0
- starplot/plotters/legend.py +247 -0
- starplot/plotters/milkyway.py +8 -5
- starplot/plotters/stars.py +5 -3
- starplot/projections.py +155 -55
- starplot/styles/base.py +98 -22
- starplot/styles/ext/antique.yml +0 -1
- starplot/styles/ext/blue_dark.yml +0 -1
- starplot/styles/ext/blue_gold.yml +60 -52
- starplot/styles/ext/blue_light.yml +0 -1
- starplot/styles/ext/blue_medium.yml +7 -7
- starplot/styles/ext/blue_night.yml +178 -0
- starplot/styles/ext/cb_wong.yml +0 -1
- starplot/styles/ext/gradient_presets.yml +158 -0
- starplot/styles/ext/grayscale.yml +0 -1
- starplot/styles/ext/grayscale_dark.yml +0 -1
- starplot/styles/ext/nord.yml +0 -1
- starplot/styles/extensions.py +90 -0
- starplot/zenith.py +174 -0
- {starplot-0.15.8.dist-info → starplot-0.16.1.dist-info}/METADATA +18 -11
- {starplot-0.15.8.dist-info → starplot-0.16.1.dist-info}/RECORD +42 -36
- starplot/settings.py +0 -26
- {starplot-0.15.8.dist-info → starplot-0.16.1.dist-info}/WHEEL +0 -0
- {starplot-0.15.8.dist-info → starplot-0.16.1.dist-info}/entry_points.txt +0 -0
- {starplot-0.15.8.dist-info → starplot-0.16.1.dist-info}/licenses/LICENSE +0 -0
starplot/plotters/stars.py
CHANGED
|
@@ -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(
|
|
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
|
|
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
|
|
7
|
-
|
|
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
|
-
|
|
13
|
-
|
|
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
|
-
|
|
19
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
201
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
"""
|
|
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=
|
|
776
|
+
font_size=70,
|
|
696
777
|
font_weight=FontWeightEnum.BOLD,
|
|
697
778
|
zorder=ZOrderEnum.LAYER_5,
|
|
698
|
-
line_spacing=
|
|
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(
|
|
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=
|
|
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)
|
starplot/styles/ext/antique.yml
CHANGED
|
@@ -1,16 +1,50 @@
|
|
|
1
1
|
# blue_gold
|
|
2
|
-
|
|
3
2
|
background_color: rgb(46, 61, 74)
|
|
4
|
-
figure_background_color:
|
|
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%,
|
|
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
|
-
|
|
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,
|
|
88
|
-
edge_color: hsl(328,
|
|
93
|
+
color: hsl(328, 30%, 56%)
|
|
94
|
+
edge_color: hsl(328, 63%, 24%)
|
|
89
95
|
label:
|
|
90
|
-
font_color: hsl(328,
|
|
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%,
|
|
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(
|
|
106
|
-
edge_color:
|
|
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(
|
|
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:
|
|
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'
|