starplot 0.18.3__py2.py3-none-any.whl → 0.19.2__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 +33 -27
- starplot/config.py +11 -0
- starplot/data/__init__.py +3 -5
- starplot/data/catalogs.py +24 -12
- starplot/data/constellations.py +1 -0
- starplot/data/db.py +1 -7
- starplot/geod.py +3 -4
- starplot/geometry.py +17 -1
- starplot/mixins.py +11 -0
- starplot/models/__init__.py +3 -1
- starplot/models/constellation.py +20 -3
- starplot/models/milky_way.py +30 -0
- starplot/models/moon.py +1 -1
- starplot/models/observer.py +11 -2
- starplot/models/planet.py +1 -1
- starplot/models/sun.py +1 -1
- starplot/plots/__init__.py +6 -0
- starplot/{base.py → plots/base.py} +107 -456
- starplot/{horizon.py → plots/horizon.py} +12 -10
- starplot/{map.py → plots/map.py} +11 -7
- starplot/{optic.py → plots/optic.py} +21 -30
- starplot/{zenith.py → plots/zenith.py} +37 -8
- starplot/plotters/__init__.py +9 -7
- starplot/plotters/arrow.py +1 -1
- starplot/plotters/constellations.py +46 -61
- starplot/plotters/dsos.py +33 -16
- starplot/plotters/experimental.py +0 -1
- starplot/plotters/milkyway.py +15 -6
- starplot/plotters/stars.py +19 -36
- starplot/plotters/text.py +524 -0
- starplot/styles/__init__.py +4 -4
- starplot/styles/base.py +1 -13
- {starplot-0.18.3.dist-info → starplot-0.19.2.dist-info}/METADATA +2 -1
- {starplot-0.18.3.dist-info → starplot-0.19.2.dist-info}/RECORD +37 -35
- starplot/data/library/sky.db +0 -0
- {starplot-0.18.3.dist-info → starplot-0.19.2.dist-info}/WHEEL +0 -0
- {starplot-0.18.3.dist-info → starplot-0.19.2.dist-info}/entry_points.txt +0 -0
- {starplot-0.18.3.dist-info → starplot-0.19.2.dist-info}/licenses/LICENSE +0 -0
starplot/plotters/dsos.py
CHANGED
|
@@ -15,6 +15,7 @@ from starplot.models.dso import (
|
|
|
15
15
|
)
|
|
16
16
|
from starplot.styles import MarkerSymbolEnum
|
|
17
17
|
from starplot.profile import profile
|
|
18
|
+
from starplot.plotters.text import CollisionHandler
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
class DsoPlotterMixin:
|
|
@@ -147,33 +148,37 @@ class DsoPlotterMixin:
|
|
|
147
148
|
self,
|
|
148
149
|
where: list = None,
|
|
149
150
|
where_labels: list = None,
|
|
150
|
-
|
|
151
|
+
where_true_size: list = None,
|
|
151
152
|
legend_labels: Mapping[DsoType, str] = DSO_LEGEND_LABELS,
|
|
152
153
|
alpha_fn: Callable[[DSO], float] = None,
|
|
153
154
|
label_fn: Callable[[DSO], str] = DSO.get_label,
|
|
154
155
|
sql: str = None,
|
|
155
156
|
sql_labels: str = None,
|
|
156
157
|
catalog: Catalog = OPEN_NGC,
|
|
158
|
+
collision_handler: CollisionHandler = None,
|
|
157
159
|
):
|
|
158
160
|
"""
|
|
159
|
-
Plots Deep Sky Objects (DSOs)
|
|
161
|
+
Plots Deep Sky Objects (DSOs).
|
|
160
162
|
|
|
161
163
|
Args:
|
|
162
164
|
where: A list of expressions that determine which DSOs to plot. See [Selecting Objects](/reference-selecting-objects/) for details.
|
|
163
|
-
where_labels: A list of expressions that determine which DSOs are labeled on the plot. See [Selecting Objects](/reference-selecting-objects/) for details.
|
|
164
|
-
|
|
165
|
-
labels: A dictionary that maps DSO names (as specified in OpenNGC) to the label that'll be plotted for that object. By default, the DSO's name in OpenNGC will be used as the label. If you want to hide all labels, then set this arg to `None`.
|
|
165
|
+
where_labels: A list of expressions that determine which DSOs are labeled on the plot. By default all DSOs are labeled. See [Selecting Objects](/reference-selecting-objects/) for details.
|
|
166
|
+
where_true_size: A list of expressions that determine which DSOs are plotted as their true apparent size in the sky. By default all DSOs are plotted as their true size.
|
|
166
167
|
legend_labels: A dictionary that maps a `DsoType` to the legend label that'll be plotted for that type of DSO. If you want to hide all DSO legend labels, then set this arg to `None`.
|
|
167
168
|
alpha_fn: Callable for calculating the alpha value (aka "opacity") of each DSO. If `None`, then the marker style's alpha will be used.
|
|
168
169
|
label_fn: Callable for determining the label of each DSO.
|
|
169
170
|
sql: SQL query for selecting DSOs (table name is `_`). This query will be applied _after_ any filters in the `where` kwarg.
|
|
170
171
|
sql_labels: SQL query for selecting DSOs that will be labeled (table name is `_`). Applied _after_ any filters in the `where_labels` kwarg.
|
|
172
|
+
catalog: The catalog of DSOs to use -- see [catalogs overview](/data/overview/) for details
|
|
173
|
+
collision_handler: An instance of [CollisionHandler][starplot.CollisionHandler] that describes what to do on label collisions with other labels, markers, etc. If `None`, then the collision handler of the plot will be used.
|
|
171
174
|
"""
|
|
172
175
|
|
|
173
176
|
# TODO: add kwarg styles
|
|
174
177
|
|
|
175
178
|
where = where or []
|
|
176
179
|
where_labels = where_labels or []
|
|
180
|
+
where_true_size = where_true_size or []
|
|
181
|
+
handler = collision_handler or self.collision_handler
|
|
177
182
|
|
|
178
183
|
if legend_labels is None:
|
|
179
184
|
legend_labels = {}
|
|
@@ -183,21 +188,23 @@ class DsoPlotterMixin:
|
|
|
183
188
|
extent = self._extent_mask()
|
|
184
189
|
dso_results = load(extent=extent, filters=where, sql=sql, catalog=catalog)
|
|
185
190
|
|
|
186
|
-
|
|
191
|
+
dsos_labeled = dso_results
|
|
187
192
|
for f in where_labels:
|
|
188
|
-
|
|
193
|
+
dsos_labeled = dsos_labeled.filter(f)
|
|
194
|
+
|
|
195
|
+
dsos_true_size = dso_results
|
|
196
|
+
for f in where_true_size:
|
|
197
|
+
dsos_true_size = dsos_true_size.filter(f)
|
|
189
198
|
|
|
190
199
|
if sql_labels:
|
|
191
|
-
result = (
|
|
192
|
-
dso_results_labeled.alias("_").sql(sql_labels).select("pk").execute()
|
|
193
|
-
)
|
|
200
|
+
result = dsos_labeled.alias("_").sql(sql_labels).select("pk").execute()
|
|
194
201
|
pks = result["pk"].to_list()
|
|
195
|
-
|
|
202
|
+
dsos_labeled = dsos_labeled.filter(_.pk.isin(pks))
|
|
196
203
|
|
|
197
|
-
label_pks =
|
|
204
|
+
label_pks = dsos_labeled.select("pk").to_pandas()["pk"].tolist()
|
|
205
|
+
true_size_pks = dsos_true_size.select("pk").to_pandas()["pk"].tolist()
|
|
198
206
|
|
|
199
|
-
results_df = dso_results.to_pandas()
|
|
200
|
-
results_df = results_df.replace({np.nan: None})
|
|
207
|
+
results_df = dso_results.to_pandas().replace({np.nan: None})
|
|
201
208
|
|
|
202
209
|
for d in results_df.itertuples():
|
|
203
210
|
ra = d.ra
|
|
@@ -221,7 +228,9 @@ class DsoPlotterMixin:
|
|
|
221
228
|
if _dso.pk not in label_pks:
|
|
222
229
|
label = None
|
|
223
230
|
|
|
224
|
-
|
|
231
|
+
_true_size = _dso.pk in true_size_pks
|
|
232
|
+
|
|
233
|
+
if _true_size and d.size is not None:
|
|
225
234
|
if "Polygon" == str(d.geometry.geom_type):
|
|
226
235
|
self._plot_dso_polygon(d.geometry, style)
|
|
227
236
|
|
|
@@ -257,7 +266,14 @@ class DsoPlotterMixin:
|
|
|
257
266
|
)
|
|
258
267
|
|
|
259
268
|
if label:
|
|
260
|
-
self.text(
|
|
269
|
+
self.text(
|
|
270
|
+
label,
|
|
271
|
+
ra,
|
|
272
|
+
dec,
|
|
273
|
+
style.label,
|
|
274
|
+
collision_handler=handler,
|
|
275
|
+
gid=f"dso-{d.type}-label",
|
|
276
|
+
)
|
|
261
277
|
|
|
262
278
|
self._add_legend_handle_marker(legend_label, style.marker)
|
|
263
279
|
|
|
@@ -269,6 +285,7 @@ class DsoPlotterMixin:
|
|
|
269
285
|
style=style,
|
|
270
286
|
label=label,
|
|
271
287
|
legend_label=legend_label,
|
|
288
|
+
collision_handler=handler,
|
|
272
289
|
skip_bounds_check=True,
|
|
273
290
|
gid_marker=f"dso-{d.type}-marker",
|
|
274
291
|
gid_label=f"dso-{d.type}-label",
|
starplot/plotters/milkyway.py
CHANGED
|
@@ -1,32 +1,41 @@
|
|
|
1
1
|
from shapely.ops import unary_union
|
|
2
2
|
|
|
3
|
+
from ibis import _
|
|
4
|
+
|
|
3
5
|
from starplot.data import db
|
|
6
|
+
from starplot.data.catalogs import Catalog, MILKY_WAY
|
|
4
7
|
from starplot.styles import PolygonStyle
|
|
5
8
|
from starplot.styles.helpers import use_style
|
|
6
9
|
from starplot.geometry import split_polygon_at_zero
|
|
7
10
|
from starplot.profile import profile
|
|
11
|
+
from starplot.models.milky_way import from_tuple
|
|
8
12
|
|
|
9
13
|
|
|
10
14
|
class MilkyWayPlotterMixin:
|
|
11
15
|
@profile
|
|
12
16
|
@use_style(PolygonStyle, "milky_way")
|
|
13
|
-
def milky_way(self, style: PolygonStyle = None):
|
|
17
|
+
def milky_way(self, style: PolygonStyle = None, catalog: Catalog = MILKY_WAY):
|
|
14
18
|
"""
|
|
15
19
|
Plots the Milky Way
|
|
16
20
|
|
|
17
21
|
Args:
|
|
18
22
|
style: Styling of the Milky Way. If None, then the plot's style (specified when creating the plot) will be used
|
|
23
|
+
catalog: Catalog to use for Milky Way polygons
|
|
19
24
|
"""
|
|
20
25
|
con = db.connect()
|
|
21
|
-
mw =
|
|
26
|
+
mw = catalog._load(connection=con, table_name="milky_way")
|
|
27
|
+
mw = mw.mutate(
|
|
28
|
+
geometry=_.geometry.cast("geometry"), # cast WKB to geometry type
|
|
29
|
+
)
|
|
22
30
|
|
|
23
31
|
extent = self._extent_mask()
|
|
24
|
-
|
|
32
|
+
df = mw.filter(_.geometry.intersects(extent)).to_pandas()
|
|
25
33
|
|
|
26
|
-
|
|
34
|
+
milky_ways = [from_tuple(m) for m in df.itertuples()]
|
|
27
35
|
|
|
28
|
-
|
|
29
|
-
|
|
36
|
+
polygons = []
|
|
37
|
+
for milky_way in milky_ways:
|
|
38
|
+
polygons.extend(split_polygon_at_zero(milky_way.geometry))
|
|
30
39
|
|
|
31
40
|
mw_union = unary_union(polygons)
|
|
32
41
|
|
starplot/plotters/stars.py
CHANGED
|
@@ -4,7 +4,7 @@ from typing import Callable
|
|
|
4
4
|
import rtree
|
|
5
5
|
import numpy as np
|
|
6
6
|
from ibis import _ as ibis_table
|
|
7
|
-
from skyfield.api import Star as SkyfieldStar
|
|
7
|
+
from skyfield.api import Star as SkyfieldStar
|
|
8
8
|
|
|
9
9
|
from starplot import callables
|
|
10
10
|
from starplot.data import stars
|
|
@@ -13,6 +13,7 @@ from starplot.data.translations import translate
|
|
|
13
13
|
from starplot.models.star import Star, from_tuple
|
|
14
14
|
from starplot.styles import ObjectStyle, use_style
|
|
15
15
|
from starplot.profile import profile
|
|
16
|
+
from starplot.plotters.text import CollisionHandler
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
class StarPlotterMixin:
|
|
@@ -65,6 +66,7 @@ class StarPlotterMixin:
|
|
|
65
66
|
bayer_labels: bool,
|
|
66
67
|
flamsteed_labels: bool,
|
|
67
68
|
label_fn: Callable[[Star], str],
|
|
69
|
+
collision_handler: CollisionHandler,
|
|
68
70
|
):
|
|
69
71
|
_bayer = []
|
|
70
72
|
_flamsteed = []
|
|
@@ -100,7 +102,7 @@ class StarPlotterMixin:
|
|
|
100
102
|
marker_size=star_sizes[i],
|
|
101
103
|
scale=self.scale,
|
|
102
104
|
),
|
|
103
|
-
|
|
105
|
+
collision_handler=collision_handler,
|
|
104
106
|
gid="stars-label-name",
|
|
105
107
|
)
|
|
106
108
|
|
|
@@ -121,7 +123,7 @@ class StarPlotterMixin:
|
|
|
121
123
|
marker_size=star_size,
|
|
122
124
|
scale=self.scale,
|
|
123
125
|
),
|
|
124
|
-
|
|
126
|
+
collision_handler=collision_handler,
|
|
125
127
|
gid="stars-label-bayer",
|
|
126
128
|
)
|
|
127
129
|
|
|
@@ -135,7 +137,7 @@ class StarPlotterMixin:
|
|
|
135
137
|
marker_size=star_size,
|
|
136
138
|
scale=self.scale,
|
|
137
139
|
),
|
|
138
|
-
|
|
140
|
+
collision_handler=collision_handler,
|
|
139
141
|
gid="stars-label-flamsteed",
|
|
140
142
|
)
|
|
141
143
|
|
|
@@ -163,22 +165,15 @@ class StarPlotterMixin:
|
|
|
163
165
|
flamsteed_labels: bool = False,
|
|
164
166
|
sql: str = None,
|
|
165
167
|
sql_labels: str = None,
|
|
166
|
-
|
|
167
|
-
**kwargs,
|
|
168
|
+
collision_handler: CollisionHandler = None,
|
|
168
169
|
):
|
|
169
170
|
"""
|
|
170
171
|
Plots stars
|
|
171
172
|
|
|
172
|
-
Labels for stars are determined in this order:
|
|
173
|
-
|
|
174
|
-
1. Return value from `label_fn`
|
|
175
|
-
2. Value for star's HIP id in `labels`
|
|
176
|
-
3. IAU-designated name, as listed in the [data reference](/data/star-designations/)
|
|
177
|
-
|
|
178
173
|
Args:
|
|
179
174
|
where: A list of expressions that determine which stars to plot. See [Selecting Objects](/reference-selecting-objects/) for details.
|
|
180
175
|
where_labels: A list of expressions that determine which stars are labeled on the plot (this includes all labels: name, Bayer, and Flamsteed). If you want to hide **all** labels, then set this arg to `[False]`. See [Selecting Objects](/reference-selecting-objects/) for details.
|
|
181
|
-
catalog: The catalog of stars to use
|
|
176
|
+
catalog: The catalog of stars to use -- see [catalogs overview](/data/overview/) for details
|
|
182
177
|
style: If `None`, then the plot's style for stars will be used
|
|
183
178
|
size_fn: Callable for calculating the marker size of each star. If `None`, then the marker style's size will be used.
|
|
184
179
|
alpha_fn: Callable for calculating the alpha value (aka "opacity") of each star. If `None`, then the marker style's alpha will be used.
|
|
@@ -189,6 +184,7 @@ class StarPlotterMixin:
|
|
|
189
184
|
flamsteed_labels: If True, then Flamsteed number labels for stars will be plotted.
|
|
190
185
|
sql: SQL query for selecting stars (table name is `_`). This query will be applied _after_ any filters in the `where` kwarg.
|
|
191
186
|
sql_labels: SQL query for selecting stars that will be labeled (table name is `_`). Applied _after_ any filters in the `where_labels` kwarg.
|
|
187
|
+
collision_handler: An instance of [CollisionHandler][starplot.CollisionHandler] that describes what to do on label collisions with other labels, markers, etc. If `None`, then the collision handler of the plot will be used.
|
|
192
188
|
"""
|
|
193
189
|
|
|
194
190
|
# fallback to style if callables are None
|
|
@@ -199,6 +195,7 @@ class StarPlotterMixin:
|
|
|
199
195
|
alpha_fn = alpha_fn or (lambda d: style.marker.alpha)
|
|
200
196
|
color_fn = color_fn or (lambda d: color_hex)
|
|
201
197
|
|
|
198
|
+
handler = collision_handler or self.collision_handler
|
|
202
199
|
where = where or []
|
|
203
200
|
where_labels = where_labels or []
|
|
204
201
|
stars_to_index = []
|
|
@@ -221,30 +218,15 @@ class StarPlotterMixin:
|
|
|
221
218
|
stars_df = star_results.to_pandas()
|
|
222
219
|
stars_df["ra_hours"], stars_df["dec_degrees"] = (stars_df.ra / 15, stars_df.dec)
|
|
223
220
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
.observe(SkyfieldStar.from_dataframe(stars_df))
|
|
232
|
-
.apparent()
|
|
233
|
-
)
|
|
234
|
-
# we only need altitude
|
|
235
|
-
stars_alt, _, _ = stars_apparent.altaz()
|
|
236
|
-
stars_df["alt"] = stars_alt.degrees
|
|
237
|
-
stars_df = stars_df[stars_df["alt"] > 0]
|
|
238
|
-
else:
|
|
239
|
-
nearby_stars = SkyfieldStar.from_dataframe(stars_df)
|
|
240
|
-
astrometric = self.earth.at(self.observer.timescale).observe(nearby_stars)
|
|
241
|
-
stars_ra, stars_dec, _ = astrometric.radec()
|
|
242
|
-
stars_df["ra"], stars_df["dec"] = (
|
|
243
|
-
stars_ra.hours * 15,
|
|
244
|
-
stars_dec.degrees,
|
|
245
|
-
)
|
|
246
|
-
|
|
221
|
+
nearby_stars = SkyfieldStar.from_dataframe(stars_df)
|
|
222
|
+
astrometric = self.earth.at(self.observer.timescale).observe(nearby_stars)
|
|
223
|
+
stars_ra, stars_dec, _ = astrometric.radec()
|
|
224
|
+
stars_df["ra"], stars_df["dec"] = (
|
|
225
|
+
stars_ra.hours * 15,
|
|
226
|
+
stars_dec.degrees,
|
|
227
|
+
)
|
|
247
228
|
stars_df = self._prepare_star_coords(stars_df)
|
|
229
|
+
|
|
248
230
|
starz = []
|
|
249
231
|
rtree_id = 1
|
|
250
232
|
|
|
@@ -330,4 +312,5 @@ class StarPlotterMixin:
|
|
|
330
312
|
bayer_labels,
|
|
331
313
|
flamsteed_labels,
|
|
332
314
|
label_fn,
|
|
315
|
+
handler,
|
|
333
316
|
)
|