starplot 0.20.5__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 +59 -0
- starplot/callables.py +176 -0
- starplot/cli.py +29 -0
- starplot/config.py +80 -0
- starplot/coordinates.py +7 -0
- starplot/data/__init__.py +22 -0
- starplot/data/catalogs.py +356 -0
- starplot/data/constellations.py +71 -0
- starplot/data/db.py +33 -0
- starplot/data/dsos.py +85 -0
- starplot/data/ecliptic.py +201 -0
- starplot/data/library/constellation_names.parquet +0 -0
- starplot/data/library/dso_names.parquet +0 -0
- starplot/data/library/readme.md +1 -0
- starplot/data/library/star_designations.parquet +0 -0
- starplot/data/stars.py +79 -0
- starplot/data/translations.py +408 -0
- starplot/data/utils.py +35 -0
- starplot/geometry.py +319 -0
- starplot/mixins.py +360 -0
- starplot/models/__init__.py +21 -0
- starplot/models/base.py +77 -0
- starplot/models/comet.py +302 -0
- starplot/models/constellation.py +151 -0
- starplot/models/dso.py +317 -0
- starplot/models/milky_way.py +30 -0
- starplot/models/moon.py +130 -0
- starplot/models/objects.py +29 -0
- starplot/models/observer.py +125 -0
- starplot/models/optics.py +342 -0
- starplot/models/planet.py +137 -0
- starplot/models/satellite.py +138 -0
- starplot/models/star.py +253 -0
- starplot/models/sun.py +62 -0
- starplot/plots/__init__.py +7 -0
- starplot/plots/base.py +1023 -0
- starplot/plots/galaxy.py +372 -0
- starplot/plots/horizon.py +543 -0
- starplot/plots/map.py +515 -0
- starplot/plots/optic.py +469 -0
- starplot/plots/zenith.py +217 -0
- starplot/plotters/__init__.py +9 -0
- starplot/plotters/arrow.py +174 -0
- starplot/plotters/constellations.py +298 -0
- starplot/plotters/debug.py +21 -0
- starplot/plotters/dsos.py +294 -0
- starplot/plotters/experimental.py +722 -0
- starplot/plotters/gradients.py +153 -0
- starplot/plotters/legend.py +253 -0
- starplot/plotters/milkyway.py +51 -0
- starplot/plotters/stars.py +319 -0
- starplot/plotters/text.py +802 -0
- starplot/profile.py +16 -0
- starplot/projections.py +184 -0
- starplot/styles/__init__.py +6 -0
- starplot/styles/base.py +1344 -0
- starplot/styles/ext/antique.yml +175 -0
- starplot/styles/ext/blue_dark.yml +163 -0
- starplot/styles/ext/blue_gold.yml +147 -0
- starplot/styles/ext/blue_light.yml +123 -0
- starplot/styles/ext/blue_medium.yml +142 -0
- starplot/styles/ext/blue_night.yml +185 -0
- starplot/styles/ext/cb_wong.yml +124 -0
- starplot/styles/ext/color_print.yml +111 -0
- starplot/styles/ext/gradient_presets.yml +158 -0
- starplot/styles/ext/grayscale.yml +94 -0
- starplot/styles/ext/grayscale_dark.yml +136 -0
- starplot/styles/ext/map.yml +12 -0
- starplot/styles/ext/nord.yml +158 -0
- starplot/styles/ext/optic.yml +20 -0
- starplot/styles/ext/publication.yml +8 -0
- starplot/styles/extensions.py +129 -0
- starplot/styles/fonts-library/gfs-didot/DESCRIPTION.en_us.html +9 -0
- starplot/styles/fonts-library/gfs-didot/GFSDidot-Regular.ttf +0 -0
- starplot/styles/fonts-library/gfs-didot/METADATA.pb +16 -0
- starplot/styles/fonts-library/gfs-didot/OFL.txt +94 -0
- starplot/styles/fonts-library/inter/Inter-Bold.ttf +0 -0
- starplot/styles/fonts-library/inter/Inter-BoldItalic.ttf +0 -0
- starplot/styles/fonts-library/inter/Inter-ExtraBold.ttf +0 -0
- starplot/styles/fonts-library/inter/Inter-ExtraLight.ttf +0 -0
- starplot/styles/fonts-library/inter/Inter-ExtraLightItalic.ttf +0 -0
- starplot/styles/fonts-library/inter/Inter-Italic.ttf +0 -0
- starplot/styles/fonts-library/inter/Inter-Light.ttf +0 -0
- starplot/styles/fonts-library/inter/Inter-LightItalic.ttf +0 -0
- starplot/styles/fonts-library/inter/Inter-Regular.ttf +0 -0
- starplot/styles/fonts-library/inter/Inter-SemiBold.ttf +0 -0
- starplot/styles/fonts-library/inter/Inter-SemiBoldItalic.ttf +0 -0
- starplot/styles/fonts-library/inter/LICENSE.txt +92 -0
- starplot/styles/fonts.py +15 -0
- starplot/styles/helpers.py +93 -0
- starplot/styles/markers.py +308 -0
- starplot/utils.py +169 -0
- starplot/warnings.py +21 -0
- starplot-0.20.5.dist-info/METADATA +146 -0
- starplot-0.20.5.dist-info/RECORD +98 -0
- starplot-0.20.5.dist-info/WHEEL +4 -0
- starplot-0.20.5.dist-info/entry_points.txt +3 -0
- starplot-0.20.5.dist-info/licenses/LICENSE +21 -0
starplot/__init__.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# ruff: noqa: F401,F403
|
|
2
|
+
|
|
3
|
+
"""Star charts and maps of the sky"""
|
|
4
|
+
|
|
5
|
+
__version__ = "0.20.5"
|
|
6
|
+
|
|
7
|
+
from .plots import (
|
|
8
|
+
MapPlot,
|
|
9
|
+
HorizonPlot,
|
|
10
|
+
OpticPlot,
|
|
11
|
+
ZenithPlot,
|
|
12
|
+
GalaxyPlot,
|
|
13
|
+
)
|
|
14
|
+
from .models import (
|
|
15
|
+
DSO,
|
|
16
|
+
DsoType,
|
|
17
|
+
Star,
|
|
18
|
+
Constellation,
|
|
19
|
+
ConstellationBorder,
|
|
20
|
+
Comet,
|
|
21
|
+
Planet,
|
|
22
|
+
Moon,
|
|
23
|
+
Sun,
|
|
24
|
+
ObjectList,
|
|
25
|
+
Scope,
|
|
26
|
+
Binoculars,
|
|
27
|
+
Reflector,
|
|
28
|
+
Refractor,
|
|
29
|
+
Camera,
|
|
30
|
+
Satellite,
|
|
31
|
+
Observer,
|
|
32
|
+
MilkyWay,
|
|
33
|
+
)
|
|
34
|
+
from .data import Catalog
|
|
35
|
+
from .styles import *
|
|
36
|
+
from .projections import *
|
|
37
|
+
from .config import settings
|
|
38
|
+
from .plotters.text import CollisionHandler
|
|
39
|
+
|
|
40
|
+
from ibis import _
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
import contextlib
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@contextlib.contextmanager
|
|
47
|
+
def override_settings(**kwargs):
|
|
48
|
+
original = {}
|
|
49
|
+
|
|
50
|
+
for key, value in kwargs.items():
|
|
51
|
+
original[key] = getattr(settings, key, None)
|
|
52
|
+
setattr(settings, key, value)
|
|
53
|
+
|
|
54
|
+
try:
|
|
55
|
+
yield
|
|
56
|
+
|
|
57
|
+
finally:
|
|
58
|
+
for key, value in original.items():
|
|
59
|
+
setattr(settings, key, value)
|
starplot/callables.py
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
from typing import Callable
|
|
4
|
+
|
|
5
|
+
from starplot.models import Star
|
|
6
|
+
from starplot.utils import bv_to_hex_color
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def size_by_magnitude_factory(
|
|
10
|
+
threshold: float,
|
|
11
|
+
over_threshold_size: float,
|
|
12
|
+
base: float = 20,
|
|
13
|
+
) -> Callable[[Star], float]:
|
|
14
|
+
"""
|
|
15
|
+
Creates a new version of `size_by_magnitude_log` with a custom threshold and base multiplier:
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
if magnitude >= threshold:
|
|
19
|
+
size = over_threshold_size
|
|
20
|
+
else:
|
|
21
|
+
size = base ** math.log(threshold - magnitude)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
threshold: The threshold at which size will be a constant value. In other words, if an object's magnitude is more than or equal to this number, then its size will be the constant `under_threshold_size`
|
|
26
|
+
over_threshold_size: Size for objects that have a magnitude greater than or equal to the treshold
|
|
27
|
+
base: Base for objects that have a magnitude less than the threshold
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
A callable for calculating size based on magnitude
|
|
31
|
+
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def size_fn(star: Star) -> float:
|
|
35
|
+
m = star.magnitude
|
|
36
|
+
if m >= threshold:
|
|
37
|
+
size = over_threshold_size
|
|
38
|
+
else:
|
|
39
|
+
size = base ** math.log(threshold - m)
|
|
40
|
+
|
|
41
|
+
return size * 9
|
|
42
|
+
|
|
43
|
+
return size_fn
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
_size_by_magnitude_default = size_by_magnitude_factory(7.6, 4)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def size_by_magnitude_log(star: Star) -> float:
|
|
50
|
+
"""
|
|
51
|
+
Calculates size by logarithmic scale of magnitude:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
if magnitude >= 7.6:
|
|
55
|
+
size = 2.36
|
|
56
|
+
else:
|
|
57
|
+
size = 20 ** math.log(8 - magnitude)
|
|
58
|
+
```
|
|
59
|
+
"""
|
|
60
|
+
return _size_by_magnitude_default(star)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def size_by_magnitude(star: Star) -> float:
|
|
64
|
+
"""
|
|
65
|
+
Simple sizing by magnitude, using a step size of 1.
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
if mag <= 0:
|
|
69
|
+
size = 3800
|
|
70
|
+
elif mag <= 1: # 0..1
|
|
71
|
+
size = 2400
|
|
72
|
+
elif mag <= 2: # 1..2
|
|
73
|
+
size = 1600
|
|
74
|
+
elif mag <= 3: # 2..3
|
|
75
|
+
size = 1000
|
|
76
|
+
elif mag <= 4: # 3..4
|
|
77
|
+
size = 600
|
|
78
|
+
elif mag <= 5: # 4..5
|
|
79
|
+
size = 300
|
|
80
|
+
elif mag <= 6: # 5..6
|
|
81
|
+
size = 120
|
|
82
|
+
elif mag <= 7: # 6..7
|
|
83
|
+
size = 60
|
|
84
|
+
elif mag <= 8: # 7..8
|
|
85
|
+
size = 40
|
|
86
|
+
else: # > 8
|
|
87
|
+
size = 20
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
"""
|
|
91
|
+
mag = star.magnitude
|
|
92
|
+
size = 0
|
|
93
|
+
if mag <= 0:
|
|
94
|
+
size = 3800
|
|
95
|
+
elif mag <= 1: # 0..1
|
|
96
|
+
size = 2400
|
|
97
|
+
elif mag <= 2: # 1..2
|
|
98
|
+
size = 1600
|
|
99
|
+
elif mag <= 3: # 2..3
|
|
100
|
+
size = 1000
|
|
101
|
+
elif mag <= 4: # 3..4
|
|
102
|
+
size = 600
|
|
103
|
+
elif mag <= 5: # 4..5
|
|
104
|
+
size = 300
|
|
105
|
+
elif mag <= 6: # 5..6
|
|
106
|
+
size = 120
|
|
107
|
+
elif mag <= 7: # 6..7
|
|
108
|
+
size = 60
|
|
109
|
+
elif mag <= 8: # 7..8
|
|
110
|
+
size = 40
|
|
111
|
+
else: # > 8
|
|
112
|
+
size = 20
|
|
113
|
+
|
|
114
|
+
return size
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def size_by_magnitude_simple(star: Star) -> float:
|
|
118
|
+
"""Very simple sizer by magnitude for map plots"""
|
|
119
|
+
m = star.magnitude
|
|
120
|
+
if m < 1.6:
|
|
121
|
+
return (9 - m) ** 2.85
|
|
122
|
+
elif m < 4.6:
|
|
123
|
+
return (8 - m) ** 2.92
|
|
124
|
+
elif m < 5.8:
|
|
125
|
+
return (9 - m) ** 2.46
|
|
126
|
+
|
|
127
|
+
return 2.23
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def size_by_magnitude_for_optic(star: Star) -> float:
|
|
131
|
+
"""Very simple sizer by magnitude for optic plots"""
|
|
132
|
+
m = star.magnitude
|
|
133
|
+
|
|
134
|
+
if m < 4.6:
|
|
135
|
+
return (9 - m) ** 3.6 * 9
|
|
136
|
+
elif m < 5.85:
|
|
137
|
+
return (9 - m) ** 3.6 * 9
|
|
138
|
+
elif m < 9:
|
|
139
|
+
return (13 - m) ** 1.8 * 9
|
|
140
|
+
|
|
141
|
+
return 4.8 * 6
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def alpha_by_magnitude(star: Star) -> float:
|
|
145
|
+
"""
|
|
146
|
+
Basic calculator for alpha, based on magnitude:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
if magnitude < 4.6:
|
|
150
|
+
alpha = 1
|
|
151
|
+
elif magnitude < 5.8:
|
|
152
|
+
alpha = 0.9
|
|
153
|
+
else:
|
|
154
|
+
alpha = (16 - m) * 0.09
|
|
155
|
+
```
|
|
156
|
+
"""
|
|
157
|
+
m = star.magnitude
|
|
158
|
+
if m < 4.6:
|
|
159
|
+
return 1
|
|
160
|
+
elif m < 5.8:
|
|
161
|
+
return 0.9
|
|
162
|
+
|
|
163
|
+
return (16 - m) * 0.09
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def color_by_bv(star: Star) -> str:
|
|
167
|
+
"""
|
|
168
|
+
Calculates color by the object's [B-V index](https://en.wikipedia.org/wiki/Color_index)
|
|
169
|
+
|
|
170
|
+
Color hex values from: [Mitchell Charity](http://www.vendian.org/mncharity/dir3/starcolor/details.html)
|
|
171
|
+
"""
|
|
172
|
+
if math.isnan(star.bv):
|
|
173
|
+
bv = 0
|
|
174
|
+
else:
|
|
175
|
+
bv = star.bv
|
|
176
|
+
return bv_to_hex_color(bv)
|
starplot/cli.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
from starplot.styles import fonts
|
|
4
|
+
from starplot.config import settings
|
|
5
|
+
from starplot.data import db
|
|
6
|
+
from starplot.data.catalogs import download_all_catalogs
|
|
7
|
+
|
|
8
|
+
COMMANDS = ["setup"]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def setup(options):
|
|
12
|
+
print("Installing DuckDB spatial extension...")
|
|
13
|
+
db.connect() # installs spatial extension as side-effect
|
|
14
|
+
|
|
15
|
+
print("Building font cache...")
|
|
16
|
+
fonts.load()
|
|
17
|
+
|
|
18
|
+
print(f"Downloading data catalogs to: {settings.data_path}")
|
|
19
|
+
download_all_catalogs()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def main():
|
|
23
|
+
command = sys.argv[1].lower()
|
|
24
|
+
|
|
25
|
+
if command not in COMMANDS:
|
|
26
|
+
print(f"Unrecognized command: {command}")
|
|
27
|
+
|
|
28
|
+
if command == "setup":
|
|
29
|
+
setup(sys.argv[2:])
|
starplot/config.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _get_path(var_name, default) -> Path:
|
|
9
|
+
def _get():
|
|
10
|
+
value = os.environ.get(var_name, default)
|
|
11
|
+
return Path(value)
|
|
12
|
+
|
|
13
|
+
return _get
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _get_boolean(var_name, default) -> bool:
|
|
17
|
+
def _get():
|
|
18
|
+
value = os.environ.get(var_name)
|
|
19
|
+
return default if not value else bool(value.lower() == "true")
|
|
20
|
+
|
|
21
|
+
return _get
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class SvgTextType(str, Enum):
|
|
25
|
+
PATH = "path"
|
|
26
|
+
ELEMENT = "element"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class Settings:
|
|
31
|
+
data_path: Path = field(default_factory=_get_path("STARPLOT_DATA_PATH", Path.cwd()))
|
|
32
|
+
"""
|
|
33
|
+
Path that Starplot will use for data and the DuckDB spatial extension, which is required for the data backend.
|
|
34
|
+
|
|
35
|
+
Default = current working directory
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
svg_text_type: SvgTextType = field(
|
|
39
|
+
default_factory=lambda: os.environ.get(
|
|
40
|
+
"STARPLOT_SVG_TEXT_TYPE", SvgTextType.PATH
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
"""
|
|
44
|
+
Method for rendering text in SVG exports:
|
|
45
|
+
|
|
46
|
+
- `"path"` (default) will render all text as paths. This will increase the filesize,
|
|
47
|
+
but allow all viewers to see the font correctly (even if they don't have the font
|
|
48
|
+
installed on their system).
|
|
49
|
+
|
|
50
|
+
- `"element"` will render all text as an [SVG `<text>` element](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/text),
|
|
51
|
+
which means the text will be editable in graphic design applications but the text may render in a system default font if the original
|
|
52
|
+
font isn't available. **Important: when using the "element" method, text borders will be turned OFF.**
|
|
53
|
+
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
language: str = field(
|
|
57
|
+
default_factory=lambda: os.environ.get("STARPLOT_LANGUAGE", "en-US")
|
|
58
|
+
)
|
|
59
|
+
"""
|
|
60
|
+
Default language for plotted labels, as an ISO-639 code. Case insensitive.
|
|
61
|
+
|
|
62
|
+
Supported values:
|
|
63
|
+
|
|
64
|
+
- `en-us` = English (default)
|
|
65
|
+
- `es` = Spanish
|
|
66
|
+
- `fa` = Persian (Farsi). Make sure you have a Persian font installed that supports RTL (such as [Vazir](https://github.com/rastikerdar/vazir-font) or [Noto Sans Arabic](https://fonts.google.com/noto/specimen/Noto+Sans+Arabic)) and set it as the font in your plot's style.
|
|
67
|
+
- `fr` = French
|
|
68
|
+
- `it` = Italian
|
|
69
|
+
- `lt` = Lithuanian
|
|
70
|
+
- `zh-cn` = Chinese. Make sure you have a good Chinese font installed (such as [Noto Sans SC](https://fonts.google.com/noto/specimen/Noto+Sans+SC)) and you'll also need to set that as the font in your plot's style.
|
|
71
|
+
- `zh-tw` = Traditional Chinese
|
|
72
|
+
|
|
73
|
+
**🌐 Want to see another language available? Please help us add it! [Details here](https://github.com/steveberardi/starplot/tree/main/data/raw/translations).**
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
debug: bool = field(default_factory=_get_boolean("STARPLOT_DEBUG", False))
|
|
77
|
+
"""Global setting for debug mode. When this is enabled, Starplot will log debugging information and plot polygons for debugging text issues"""
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
settings = Settings()
|
starplot/coordinates.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# ruff: noqa: F401,F403
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from skyfield.api import Loader
|
|
6
|
+
|
|
7
|
+
from starplot.config import settings
|
|
8
|
+
from .catalogs import Catalog
|
|
9
|
+
|
|
10
|
+
load = Loader(settings.data_path) # used for loading ephemeris
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
HERE = Path(__file__).resolve().parent
|
|
14
|
+
|
|
15
|
+
INTERNAL_DATA_PATH = HERE / "library"
|
|
16
|
+
"""Path of starplot data"""
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class DataFiles:
|
|
20
|
+
STAR_DESIGNATIONS = INTERNAL_DATA_PATH / "star_designations.parquet"
|
|
21
|
+
CONSTELLATION_NAMES = INTERNAL_DATA_PATH / "constellation_names.parquet"
|
|
22
|
+
DSO_NAMES = INTERNAL_DATA_PATH / "dso_names.parquet"
|