starplot 0.16.3__py2.py3-none-any.whl → 0.16.5__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.

Potentially problematic release.


This version of starplot might be problematic. Click here for more details.

starplot/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Star charts and maps of the sky"""
2
2
 
3
- __version__ = "0.16.3"
3
+ __version__ = "0.16.5"
4
4
 
5
5
  from .base import BasePlot # noqa: F401
6
6
  from .map import MapPlot # noqa: F401
starplot/config.py CHANGED
@@ -1,7 +1,7 @@
1
+ import os
1
2
  from enum import Enum
2
3
  from pathlib import Path
3
-
4
- from pydantic_settings import BaseSettings, SettingsConfigDict
4
+ from dataclasses import dataclass, field
5
5
 
6
6
 
7
7
  STARPLOT_PATH = Path(__file__).resolve().parent
@@ -15,30 +15,46 @@ RAW_DATA_PATH = STARPLOT_PATH.parent.parent / "raw"
15
15
  BUILD_PATH = STARPLOT_PATH.parent.parent / "build"
16
16
 
17
17
 
18
+ def _get_path(var_name, default) -> Path:
19
+ def _get():
20
+ value = os.environ.get(var_name, default)
21
+ return Path(value)
22
+
23
+ return _get
24
+
25
+
18
26
  class SvgTextType(str, Enum):
19
27
  PATH = "path"
20
28
  ELEMENT = "element"
21
29
 
22
30
 
23
- class Settings(BaseSettings):
24
- model_config = SettingsConfigDict(env_prefix="STARPLOT_")
25
- """Configuration for the Pydantic settings model. Do not change."""
26
-
27
- download_path: Path = DATA_PATH / "downloads"
31
+ @dataclass
32
+ class Settings:
33
+ download_path: Path = field(
34
+ default_factory=_get_path("STARPLOT_DOWNLOAD_PATH", DATA_PATH / "downloads")
35
+ )
28
36
  """
29
37
  Path for downloaded data, including the Big Sky catalog, ephemeris files, etc.
30
38
 
31
39
  Default = `<starplot_source_path>/data/library/downloads/`
32
40
  """
33
41
 
34
- duckdb_extension_path: Path = DATA_PATH / "duckdb-extensions"
42
+ duckdb_extension_path: Path = field(
43
+ default_factory=_get_path(
44
+ "STARPLOT_DUCKDB_EXTENSION_PATH", DATA_PATH / "duckdb-extensions"
45
+ )
46
+ )
35
47
  """
36
48
  Path for the DuckDB spatial extension, which is required for the data backend.
37
49
 
38
50
  Default = `<starplot_source_path>/data/library/duckdb-extensions/`
39
51
  """
40
52
 
41
- svg_text_type: SvgTextType = SvgTextType.PATH
53
+ svg_text_type: SvgTextType = field(
54
+ default_factory=lambda: os.environ.get(
55
+ "STARPLOT_SVG_TEXT_TYPE", SvgTextType.PATH
56
+ )
57
+ )
42
58
  """
43
59
  Method for rendering text in SVG exports:
44
60
 
starplot/data/bigsky.py CHANGED
@@ -1,7 +1,6 @@
1
1
  import os
2
2
  from pathlib import Path
3
3
 
4
- import pandas as pd
5
4
 
6
5
  from starplot.config import settings
7
6
  from starplot.data import DataFiles, utils
@@ -46,6 +45,7 @@ def download(
46
45
  def to_parquet(source_path: str, destination_path: str):
47
46
  import pyarrow as pa
48
47
  import pyarrow.parquet as pq
48
+ import pandas as pd
49
49
 
50
50
  print("Preparing Big Sky Catalog for Starplot...")
51
51
 
@@ -1,7 +1,6 @@
1
1
  from functools import cache
2
2
 
3
- import ibis
4
- from ibis import _
3
+ from ibis import _, row_number
5
4
 
6
5
  from starplot.data import db
7
6
 
@@ -681,8 +680,8 @@ def table():
681
680
  dec=_.center_dec,
682
681
  constellation_id=_.iau_id,
683
682
  boundary=_.geometry,
684
- rowid=ibis.row_number(),
685
- sk=ibis.row_number(),
683
+ rowid=row_number(),
684
+ sk=row_number(),
686
685
  )
687
686
 
688
687
 
@@ -712,7 +711,7 @@ def load_borders(extent=None, filters=None):
712
711
  # ra=_.center_ra,
713
712
  # dec=_.center_dec,
714
713
  # constellation_id=_.iau_id,
715
- rowid=ibis.row_number(),
714
+ rowid=row_number(),
716
715
  # boundary=_.geometry,
717
716
  )
718
717
 
starplot/data/db.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from functools import cache
2
2
 
3
- import ibis
3
+ from ibis import duckdb
4
4
 
5
5
  from starplot.config import settings
6
6
  from starplot.data import DataFiles
@@ -8,7 +8,7 @@ from starplot.data import DataFiles
8
8
 
9
9
  @cache
10
10
  def connect():
11
- connection = ibis.duckdb.connect(
11
+ connection = duckdb.connect(
12
12
  DataFiles.DATABASE, read_only=True
13
13
  ) # , threads=2, memory_limit="1GB"
14
14
  connection.raw_sql(
starplot/data/dsos.py CHANGED
@@ -1,7 +1,6 @@
1
1
  from functools import cache
2
2
 
3
- import ibis
4
- from ibis import _
3
+ from ibis import _, row_number, coalesce
5
4
 
6
5
  from starplot.data import db
7
6
 
@@ -36,10 +35,10 @@ def table():
36
35
  ra=_.ra_degrees,
37
36
  dec=_.dec_degrees,
38
37
  constellation_id=_.constellation,
39
- magnitude=ibis.coalesce(_.mag_v, _.mag_b, None),
38
+ magnitude=coalesce(_.mag_v, _.mag_b, None),
40
39
  size=_.size_deg2,
41
- rowid=ibis.row_number(),
42
- sk=ibis.row_number(),
40
+ rowid=row_number(),
41
+ sk=row_number(),
43
42
  )
44
43
 
45
44
 
Binary file
starplot/data/stars.py CHANGED
@@ -1,437 +1,9 @@
1
1
  from functools import cache
2
2
 
3
- import ibis
4
- from ibis import _
3
+ from ibis import _, row_number
5
4
 
6
5
  from starplot.data import bigsky, DataFiles, db
7
6
 
8
- STAR_NAMES = {
9
- 677: "Alpheratz",
10
- 746: "Caph",
11
- 1067: "Algenib",
12
- 1547: "Citadelle",
13
- 2081: "Ankaa",
14
- 2247: "Felixvarela",
15
- 2920: "Fulu",
16
- 3179: "Schedar",
17
- 3419: "Diphda",
18
- 3479: "Cocibolca",
19
- 3821: "Achird",
20
- 4422: "Castula",
21
- 5054: "Nenque",
22
- 5348: "Wurren",
23
- 5447: "Mirach",
24
- 5529: "Emiw",
25
- 5737: "Revati",
26
- 6193: "Bharani",
27
- 6411: "Adhil",
28
- 6643: "Bélénos",
29
- 6686: "Ruchbah",
30
- 7097: "Alpherg",
31
- 7513: "Titawin",
32
- 7588: "Achernar",
33
- 7607: "Nembus",
34
- 8198: "Torcular",
35
- 8645: "Baten Kaitos",
36
- 8796: "Mothallah",
37
- 8832: "Mesarthim",
38
- 8886: "Segin",
39
- 8903: "Sheratan",
40
- 9487: "Alrescha",
41
- 9640: "Almach",
42
- 9884: "Hamal",
43
- 10826: "Mira",
44
- 11767: "Polaris",
45
- 12191: "Buna",
46
- 12706: "Kaffaljidhma",
47
- 12961: "Koeia",
48
- 13061: "Lilii Borea",
49
- 13192: "Nushagak",
50
- 13268: "Miram",
51
- 13288: "Angetenar",
52
- 13701: "Azha",
53
- 13847: "Acamar",
54
- 13993: "Ayeyarwady",
55
- 14135: "Menkar",
56
- 14576: "Algol",
57
- 14668: "Misam",
58
- 14838: "Botein",
59
- 14879: "Dalim",
60
- 15197: "Zibal",
61
- 15578: "Intan",
62
- 15863: "Mirfak",
63
- 16537: "Ran",
64
- 17096: "Tupi",
65
- 17378: "Rana",
66
- 17448: "Atik",
67
- 17489: "Celaeno",
68
- 17499: "Electra",
69
- 17531: "Taygeta",
70
- 17573: "Maia",
71
- 17579: "Asterope",
72
- 17608: "Merope",
73
- 17702: "Alcyone",
74
- 17847: "Atlas",
75
- 17851: "Pleione",
76
- 18543: "Zaurak",
77
- 18614: "Menkib",
78
- 19587: "Beid",
79
- 19780: "Rhombus",
80
- 19849: "Keid",
81
- 20205: "Prima Hyadum",
82
- 20455: "Secunda Hyadum",
83
- 20535: "Beemim",
84
- 20889: "Ain",
85
- 20894: "Chamukuy",
86
- 21109: "Hoggar",
87
- 21393: "Theemin",
88
- 21421: "Aldebaran",
89
- 21594: "Sceptrum",
90
- 22449: "Tabit",
91
- 22491: "Mouhoun",
92
- 23015: "Hassaleh",
93
- 23416: "Almaaz",
94
- 23453: "Saclateni",
95
- 23767: "Haedus",
96
- 23875: "Cursa",
97
- 24003: "Mago",
98
- 24436: "Rigel",
99
- 24608: "Capella",
100
- 25336: "Bellatrix",
101
- 25428: "Elnath",
102
- 25606: "Nihal",
103
- 25930: "Mintaka",
104
- 25985: "Arneb",
105
- 26207: "Meissa",
106
- 26241: "Hatysa",
107
- 26311: "Alnilam",
108
- 26380: "Bubup",
109
- 26451: "Tianguan",
110
- 26634: "Phact",
111
- 26727: "Alnitak",
112
- 27366: "Saiph",
113
- 27628: "Wazn",
114
- 27989: "Betelgeuse",
115
- 28360: "Menkalinan",
116
- 28380: "Mahasim",
117
- 29034: "Elkurud",
118
- 29550: "Amadioha",
119
- 29655: "Propus",
120
- 30122: "Furud",
121
- 30324: "Mirzam",
122
- 30343: "Tejat",
123
- 30438: "Canopus",
124
- 30860: "Lucilinburhuc",
125
- 30905: "Lusitânia",
126
- 31681: "Alhena",
127
- 31685: "Pipit",
128
- 31895: "Nosaxa",
129
- 32246: "Mebsuta",
130
- 32349: "Sirius",
131
- 32362: "Alzirr",
132
- 32916: "Nervia",
133
- 33579: "Adhara",
134
- 33719: "Citalá",
135
- 33856: "Unurgunite",
136
- 34045: "Muliphein",
137
- 34088: "Mekbuda",
138
- 34444: "Wezen",
139
- 35550: "Wasat",
140
- 35904: "Aludra",
141
- 36188: "Gomeisa",
142
- 36850: "Castor",
143
- 37265: "Jishui",
144
- 37279: "Procyon",
145
- 37284: "Ceibo",
146
- 37826: "Pollux",
147
- 38041: "Tapecue",
148
- 38170: "Azmidi",
149
- 39429: "Naos",
150
- 39757: "Tureis",
151
- 39953: "Regor", # not officially part of IAU recognized names
152
- 40167: "Tegmine",
153
- 40526: "Tarf",
154
- 40687: "Násti",
155
- 40881: "Piautos",
156
- 41037: "Avior",
157
- 41075: "Alsciaukat",
158
- 41704: "Muscida",
159
- 42402: "Minchir",
160
- 42446: "Gakyid",
161
- 42556: "Meleph",
162
- 42806: "Asellus Borealis",
163
- 42911: "Asellus Australis",
164
- 42913: "Alsephina",
165
- 43109: "Ashlesha",
166
- 43587: "Copernicus",
167
- 43674: "Stribor",
168
- 44066: "Acubens",
169
- 44127: "Talitha",
170
- 44471: "Alkaphrah",
171
- 44816: "Suhail",
172
- 44946: "Nahn",
173
- 45238: "Miaplacidus",
174
- 45556: "Aspidiske",
175
- 45941: "Markeb",
176
- 46390: "Alphard",
177
- 46471: "Intercrus",
178
- 46750: "Alterf",
179
- 47087: "Illyrian",
180
- 47202: "Kalausi",
181
- 47431: "Ukdah",
182
- 47508: "Subra",
183
- 48235: "Natasha",
184
- 48356: "Zhang",
185
- 48455: "Rasalas",
186
- 48615: "Felis",
187
- 48711: "Bibhā",
188
- 49637: "Yunü (Yunu)",
189
- 49669: "Regulus",
190
- 50335: "Adhafera",
191
- 50372: "Tania Borealis",
192
- 50583: "Algieba",
193
- 50801: "Tania Australis",
194
- 51624: "Shaomin",
195
- 52521: "Macondo",
196
- 53229: "Praecipua",
197
- 53721: "Chalawan",
198
- 53740: "Alkes",
199
- 53910: "Merak",
200
- 54061: "Dubhe",
201
- 54158: "Dingolay",
202
- 54872: "Zosma",
203
- 54879: "Chertan",
204
- 55174: "Hunahpú",
205
- 55203: "Alula Australis",
206
- 55219: "Alula Borealis",
207
- 55664: "Shama",
208
- 56211: "Giausar",
209
- 56508: "Formosa",
210
- 56572: "Sagarmatha",
211
- 57291: "Uklun",
212
- 57370: "Flegetonte",
213
- 57399: "Taiyangshou",
214
- 57632: "Denebola",
215
- 57757: "Zavijava",
216
- 57820: "Aniara",
217
- 58001: "Phecda",
218
- 58952: "Tonatiuh",
219
- 59199: "Alchiba",
220
- 59747: "Imai",
221
- 59774: "Megrez",
222
- 59803: "Gienah",
223
- 60129: "Zaniah",
224
- 60260: "Ginan",
225
- 60644: "Tupã",
226
- 60718: "Acrux",
227
- 60965: "Algorab",
228
- 61084: "Gacrux",
229
- 61177: "Funi",
230
- 61317: "Chara",
231
- 61359: "Kraz",
232
- 61394: "Phyllon Kissinou",
233
- 61941: "Porrima",
234
- 62223: "La Superba",
235
- 62423: "Tianyi",
236
- 62434: "Mimosa",
237
- 62956: "Alioth",
238
- 63076: "Taiyi",
239
- 63090: "Minelauva",
240
- 63125: "Cor Caroli",
241
- 63608: "Vindemiatrix",
242
- 64241: "Diadem",
243
- 65378: "Mizar",
244
- 65474: "Spica",
245
- 65477: "Alcor",
246
- 66047: "Dofida",
247
- 66192: "Liesma",
248
- 66249: "Heze",
249
- 67301: "Alkaid",
250
- 67927: "Muphrid",
251
- 68002: "Leepwal",
252
- 68702: "Hadar",
253
- 68756: "Thuban",
254
- 68933: "Menkent",
255
- 69427: "Kang",
256
- 69673: "Arcturus",
257
- 69701: "Syrma",
258
- 69732: "Xuange",
259
- 69974: "Khambalia",
260
- 70755: "Elgafar",
261
- 70890: "Proxima Centauri",
262
- 71075: "Seginus",
263
- 71681: "Toliman",
264
- 71683: "Rigil Kentaurus",
265
- 71860: "Uridim",
266
- 72105: "Izar",
267
- 72339: "Mönch",
268
- 72487: "Merga",
269
- 72607: "Kochab",
270
- 72622: "Zubenelgenubi",
271
- 72845: "Arcalís",
272
- 73136: "Baekdu",
273
- 73555: "Nekkar",
274
- 73714: "Brachium",
275
- 74785: "Zubeneschamali",
276
- 74961: "Nikawiy",
277
- 75097: "Pherkad",
278
- 75411: "Alkalurops",
279
- 75458: "Edasich",
280
- 75695: "Nusakan",
281
- 76267: "Alphecca",
282
- 76333: "Zubenelhakrabi",
283
- 76351: "Karaka",
284
- 77070: "Unukalhai",
285
- 77450: "Gudja",
286
- 78104: "Iklil",
287
- 78265: "Fang",
288
- 78401: "Dschubba",
289
- 78820: "Acrab",
290
- 79043: "Marsic",
291
- 79219: "Kamuy",
292
- 79374: "Jabbah",
293
- 79431: "Sharjah",
294
- 79593: "Yed Prior",
295
- 79882: "Yed Posterior",
296
- 80112: "Alniyat",
297
- 80331: "Athebyne",
298
- 80463: "Cujam",
299
- 80687: "Timir",
300
- 80763: "Antares",
301
- 80816: "Kornephoros",
302
- 80838: "Ogma",
303
- 80883: "Marfik",
304
- 81022: "Rosaliadecastro",
305
- 81266: "Paikauhale",
306
- 82273: "Atria",
307
- 82396: "Larawag",
308
- 82514: "Xamidimura",
309
- 82545: "Pipirima",
310
- 82651: "Mahsati",
311
- 83547: "Rapeto",
312
- 83608: "Alrakis",
313
- 83895: "Aldhibah",
314
- 84012: "Sabik",
315
- 84345: "Rasalgethi",
316
- 84379: "Sarin",
317
- 84405: "Guniibuu",
318
- 84787: "Inquill",
319
- 85670: "Rastaban",
320
- 85693: "Maasym",
321
- 85696: "Lesath",
322
- 85822: "Yildun",
323
- 85927: "Shaula",
324
- 86032: "Rasalhague",
325
- 86228: "Sargas",
326
- 86614: "Dziban",
327
- 86742: "Cebalrai",
328
- 86782: "Alruba",
329
- 86796: "Cervantes",
330
- 87108: "Bake-eo (or Bake Eo)",
331
- 87261: "Fuyue",
332
- 87585: "Grumium",
333
- 87833: "Eltanin",
334
- 87937: "Barnard's Star",
335
- 88414: "Pincoya",
336
- 88635: "Alnasl",
337
- 89341: "Polis",
338
- 89931: "Kaus Media",
339
- 90004: "Alasia",
340
- 90185: "Kaus Australis",
341
- 90344: "Fafnir",
342
- 90496: "Kaus Borealis",
343
- 91262: "Vega",
344
- 91852: "Xihe",
345
- 92420: "Sheliak",
346
- 92761: "Ainalrami",
347
- 92855: "Nunki",
348
- 92895: "Kaveh",
349
- 92946: "Alya",
350
- 93194: "Sulafat",
351
- 93506: "Ascella",
352
- 93747: "Okab",
353
- 94114: "Meridiana",
354
- 94141: "Albaldah",
355
- 94376: "Altais",
356
- 94481: "Aladfar",
357
- 94645: "Gumala",
358
- 95124: "Belel",
359
- 95241: "Arkab Prior",
360
- 95262: "Sika",
361
- 95294: "Arkab Posterior",
362
- 95347: "Rukbat",
363
- 95947: "Albireo",
364
- 96078: "Uruk",
365
- 96100: "Alsafi",
366
- 96757: "Sham",
367
- 97165: "Fawaris",
368
- 97278: "Tarazed",
369
- 97649: "Altair",
370
- 97938: "Libertas",
371
- 98036: "Alshain",
372
- 98066: "Terebellum",
373
- 98823: "Tianfu",
374
- 99473: "Antinous",
375
- 99711: "Phoenicia",
376
- 99894: "Chechia",
377
- 100064: "Algedi",
378
- 100310: "Alshat",
379
- 100345: "Dabih",
380
- 100453: "Sadr",
381
- 100751: "Peacock",
382
- 101421: "Aldulfin",
383
- 101769: "Rotanev",
384
- 101958: "Sualocin",
385
- 102098: "Deneb",
386
- 102488: "Aljanah",
387
- 102618: "Albali",
388
- 103527: "Musica",
389
- 104382: "Polaris Australis",
390
- 104987: "Kitalpha",
391
- 105199: "Alderamin",
392
- 106032: "Alfirk",
393
- 106278: "Sadalsuud",
394
- 106786: "Bunda",
395
- 106824: "Sāmaya",
396
- 106985: "Nashira",
397
- 107136: "Azelfafage",
398
- 107251: "Bosona",
399
- 107259: "Garnet Star",
400
- 107315: "Enif",
401
- 107556: "Deneb Algedi",
402
- 108085: "Aldhanab",
403
- 108375: "Itonda",
404
- 108917: "Kurhah",
405
- 109074: "Sadalmelik",
406
- 109268: "Alnair",
407
- 109427: "Biham",
408
- 110003: "Ancha",
409
- 110130: "Lang-Exster",
410
- 110395: "Sadachbia",
411
- 110813: "Lionrock",
412
- 111169: "Stellio",
413
- 111710: "Situla",
414
- 112029: "Homam",
415
- 112122: "Tiaki",
416
- 112158: "Matar",
417
- 112748: "Sadalbari",
418
- 113136: "Skat",
419
- 113288: "Tengshe",
420
- 113357: "Helvetios",
421
- 113368: "Fomalhaut",
422
- 113881: "Scheat",
423
- 113889: "Fumalsamakah",
424
- 113963: "Markab",
425
- 114322: "Ebla",
426
- 115250: "Salm",
427
- 115623: "Alkarab",
428
- 116076: "Veritate",
429
- 116084: "Poerava",
430
- 116727: "Errai",
431
- 118319: "Axólotl",
432
- }
433
- """Star names by their HIP id. You can override these values when calling `stars()`"""
434
-
435
7
 
436
8
  class StarCatalog:
437
9
  """Built-in star catalogs"""
@@ -480,8 +52,8 @@ def table(catalog: StarCatalog = StarCatalog.BIG_SKY_MAG11, table_name="stars"):
480
52
  ra_hours=_.ra_degrees / 15,
481
53
  # stars parquet does not have geometry field
482
54
  geometry=_.ra_degrees.point(_.dec_degrees),
483
- rowid=ibis.row_number(),
484
- sk=ibis.row_number(),
55
+ rowid=row_number(),
56
+ sk=row_number(),
485
57
  )
486
58
 
487
59
  stars = stars.join(
starplot/geometry.py CHANGED
@@ -143,6 +143,51 @@ def split_polygon_at_zero(polygon: Polygon) -> list[Polygon]:
143
143
  return [polygon]
144
144
 
145
145
 
146
+ def split_polygon_at_360(polygon: Polygon) -> list[Polygon]:
147
+ """
148
+ Splits a polygon at 360 degrees
149
+
150
+ Args:
151
+ polygon: Polygon that possibly needs splitting
152
+
153
+ Returns:
154
+ List of polygons
155
+ """
156
+ ra, _ = [p for p in polygon.exterior.coords.xy]
157
+
158
+ if max(ra) > 360:
159
+ polygon_1 = polygon.intersection(
160
+ Polygon(
161
+ [
162
+ [0, -90],
163
+ [360, -90],
164
+ [360, 90],
165
+ [0, 90],
166
+ [0, -90],
167
+ ]
168
+ )
169
+ )
170
+
171
+ polygon_2 = polygon.intersection(
172
+ Polygon(
173
+ [
174
+ [360, -90],
175
+ [720, -90],
176
+ [720, 90],
177
+ [360, 90],
178
+ [360, -90],
179
+ ]
180
+ )
181
+ )
182
+
183
+ p2_ra, p2_dec = [p for p in polygon_2.exterior.coords.xy]
184
+ p2_new_ra = [ra - 360 for ra in p2_ra]
185
+
186
+ return [polygon_1, Polygon(list(zip(p2_new_ra, p2_dec)))]
187
+
188
+ return [polygon]
189
+
190
+
146
191
  def random_point_in_polygon(
147
192
  polygon: Polygon, max_iterations: int = 100, seed: int = None
148
193
  ) -> Point:
starplot/horizon.py CHANGED
@@ -3,8 +3,8 @@ import math
3
3
  from functools import cache
4
4
  from typing import Callable
5
5
 
6
- import pandas as pd
7
- import geopandas as gpd
6
+ # import pandas as pd
7
+ # import geopandas as gpd
8
8
 
9
9
  from cartopy import crs as ccrs
10
10
  from matplotlib import pyplot as plt, patches
@@ -21,6 +21,7 @@ from starplot.plotters import (
21
21
  DsoPlotterMixin,
22
22
  MilkyWayPlotterMixin,
23
23
  GradientBackgroundMixin,
24
+ LegendPlotterMixin,
24
25
  )
25
26
  from starplot.styles import (
26
27
  PlotStyle,
@@ -30,7 +31,7 @@ from starplot.styles import (
30
31
  GradientDirection,
31
32
  )
32
33
 
33
- pd.options.mode.chained_assignment = None # default='warn'
34
+ # pd.options.mode.chained_assignment = None # default='warn'
34
35
 
35
36
  DEFAULT_HORIZON_STYLE = PlotStyle().extend(extensions.MAP)
36
37
 
@@ -49,11 +50,13 @@ DEFAULT_HORIZON_LABELS = {
49
50
  class HorizonPlot(
50
51
  BasePlot,
51
52
  ExtentMaskMixin,
53
+ # HorizonExtentMaskMixin,
52
54
  ConstellationPlotterMixin,
53
55
  StarPlotterMixin,
54
56
  DsoPlotterMixin,
55
57
  MilkyWayPlotterMixin,
56
58
  GradientBackgroundMixin,
59
+ LegendPlotterMixin,
57
60
  ):
58
61
  """Creates a new horizon plot.
59
62
 
@@ -122,6 +125,8 @@ class HorizonPlot(
122
125
  self.logger.debug("Creating HorizonPlot...")
123
126
  self.alt = altitude
124
127
  self.az = azimuth
128
+ self._alt = altitude
129
+ self._az = azimuth
125
130
  self.center_alt = sum(altitude) / 2
126
131
  self.center_az = sum(azimuth) / 2
127
132
 
@@ -155,16 +160,18 @@ class HorizonPlot(
155
160
  return pos_az.degrees, pos_alt.degrees
156
161
 
157
162
  def _prepare_star_coords(self, df, limit_by_altaz=True):
163
+ # import geopandas as gpd
164
+
158
165
  stars_apparent = self.observe(SkyfieldStar.from_dataframe(df)).apparent()
159
166
  nearby_stars_alt, nearby_stars_az, _ = stars_apparent.altaz()
160
167
  df["x"], df["y"] = (
161
168
  nearby_stars_az.degrees,
162
169
  nearby_stars_alt.degrees,
163
170
  )
164
- if limit_by_altaz:
165
- extent = self._extent_mask_altaz()
166
- df["_geometry_az_alt"] = gpd.points_from_xy(df.x, df.y)
167
- df = df[df["_geometry_az_alt"].intersects(extent)]
171
+ # if limit_by_altaz:
172
+ # extent = self._extent_mask_altaz()
173
+ # df["_geometry_az_alt"] = gpd.points_from_xy(df.x, df.y)
174
+ # df = df[df["_geometry_az_alt"].intersects(extent)]
168
175
 
169
176
  return df
170
177
 
starplot/map.py CHANGED
@@ -459,10 +459,6 @@ class MapPlot(
459
459
  self.logger.debug(f"Projection = {self.projection.__class__.__name__.upper()}")
460
460
 
461
461
  self._fit_to_ax()
462
-
463
- # if self.gradient_preset:
464
- # self.apply_gradient_background(self.gradient_preset)
465
-
466
462
  self._plot_background_clip_path()
467
463
 
468
464
  def _ax_to_radec(self, x, y):
starplot/mixins.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from functools import cache
2
2
 
3
3
  from shapely import Polygon, MultiPolygon
4
+ from starplot.profile import profile
4
5
 
5
6
 
6
7
  class ExtentMaskMixin:
@@ -56,6 +57,288 @@ class ExtentMaskMixin:
56
57
  )
57
58
 
58
59
 
60
+ class HorizonExtentMaskMixin:
61
+ """Experimental"""
62
+
63
+ @cache
64
+ def _extent_mask_original(self):
65
+ """
66
+ Returns shapely geometry objects of extent (RA = 0...360)
67
+
68
+ If the extent crosses equinox, then a MultiPolygon will be returned
69
+ """
70
+ if self.ra_max <= 360:
71
+ coords = [
72
+ [self.ra_min, self.dec_min],
73
+ [self.ra_max, self.dec_min],
74
+ [self.ra_max, self.dec_max],
75
+ [self.ra_min, self.dec_max],
76
+ [self.ra_min, self.dec_min],
77
+ ]
78
+ return Polygon(coords)
79
+
80
+ else:
81
+ coords_1 = [
82
+ [self.ra_min, self.dec_min],
83
+ [360, self.dec_min],
84
+ [360, self.dec_max],
85
+ [self.ra_min, self.dec_max],
86
+ [self.ra_min, self.dec_min],
87
+ ]
88
+ coords_2 = [
89
+ [0, self.dec_min],
90
+ [(self.ra_max - 360), self.dec_min],
91
+ [(self.ra_max - 360), self.dec_max],
92
+ [0, self.dec_max],
93
+ [0, self.dec_min],
94
+ ]
95
+
96
+ return MultiPolygon(
97
+ [
98
+ Polygon(coords_1),
99
+ Polygon(coords_2),
100
+ ]
101
+ )
102
+
103
+ @cache
104
+ def _extent_mask2(self):
105
+ locations = [
106
+ self.location.at(self.observer.timescale).from_altaz(
107
+ alt_degrees=self.alt[0], az_degrees=self._az[0]
108
+ ), # lower left
109
+ self.location.at(self.observer.timescale).from_altaz(
110
+ alt_degrees=self.alt[0], az_degrees=self._az[1]
111
+ ), # lower right
112
+ self.location.at(self.observer.timescale).from_altaz(
113
+ alt_degrees=self.alt[1], az_degrees=self._az[1]
114
+ ), # upper right
115
+ self.location.at(self.observer.timescale).from_altaz(
116
+ alt_degrees=self.alt[1], az_degrees=self.center_az
117
+ ), # top center
118
+ # self.location.at(self.observer.timescale).from_altaz(
119
+ # alt_degrees=self.center_alt, az_degrees=self.center_az
120
+ # ), # center
121
+ self.location.at(self.observer.timescale).from_altaz(
122
+ alt_degrees=self.alt[1], az_degrees=self._az[0]
123
+ ), # upper left
124
+ self.location.at(self.observer.timescale).from_altaz(
125
+ alt_degrees=self.alt[0], az_degrees=self._az[0]
126
+ ), # lower left
127
+ ]
128
+
129
+ # self.ra_min = None
130
+ # self.ra_max = None
131
+ # self.dec_max = None
132
+ # self.dec_min = None
133
+ from pprint import pprint
134
+ from shapely import segmentize
135
+
136
+ self.location.at(self.observer.timescale).from_altaz(
137
+ alt_degrees=self.center_alt, az_degrees=self.center_az
138
+ ) # center
139
+ print(self.alt)
140
+ print(self._az)
141
+
142
+ coords = []
143
+ for location in locations:
144
+ ra, dec, _ = location.radec()
145
+ ra = ra.hours * 15
146
+ if ra < 180:
147
+ ra += 360
148
+ dec = dec.degrees
149
+ coords.append([float(ra), float(dec)])
150
+
151
+ pprint(coords)
152
+ # coords = reversed(coords)
153
+ extent = Polygon(coords)
154
+
155
+ extent = segmentize(extent, max_segment_length=2)
156
+
157
+ self.polygon(style__fill_color="red", style__alpha=0.3, geometry=extent)
158
+ # print(extent)
159
+
160
+ return extent
161
+
162
+ @profile
163
+ @cache
164
+ def _extent_mask2(self):
165
+ """generally working"""
166
+ coords = []
167
+
168
+ alt0, alt1 = self._alt
169
+ az0, az1 = self._az
170
+
171
+ for alt in range(0, 90, 5):
172
+ for az in range(az0 - 30, az1 + 30, 5):
173
+ ra, dec, _ = (
174
+ self.location.at(self.observer.timescale)
175
+ .from_altaz(alt_degrees=alt, az_degrees=az)
176
+ .radec()
177
+ )
178
+ ra = ra.hours * 15
179
+ if ra < 180:
180
+ ra += 360
181
+ dec = dec.degrees
182
+ coords.append([float(ra), float(dec)])
183
+
184
+ extent = Polygon(coords)
185
+ from shapely import segmentize
186
+
187
+ extent = segmentize(extent, max_segment_length=1)
188
+
189
+ self.polygon(style__fill_color="red", style__alpha=0.3, geometry=extent)
190
+ # print(extent)
191
+
192
+ return extent
193
+
194
+ @profile
195
+ @cache
196
+ def _extent_mask1(self):
197
+ from shapely import segmentize
198
+
199
+ mask_altaz = self._extent_mask_altaz()
200
+
201
+ altaz_polygons = []
202
+
203
+ if str(mask_altaz.geom_type) == "MultiPolygon":
204
+ altaz_polygons = [
205
+ segmentize(p, max_segment_length=5) for p in mask_altaz.geoms
206
+ ]
207
+ else:
208
+ altaz_polygons = [segmentize(mask_altaz, max_segment_length=5)]
209
+
210
+ radec_polygons = []
211
+
212
+ for p in altaz_polygons:
213
+ coords = []
214
+
215
+ for az, alt in list(zip(*p.exterior.coords.xy)):
216
+ ra, dec, _ = (
217
+ self.location.at(self.observer.timescale)
218
+ .from_altaz(alt_degrees=alt, az_degrees=az)
219
+ .radec()
220
+ )
221
+ ra = ra.hours * 15
222
+ if ra < 180:
223
+ ra += 360
224
+ dec = dec.degrees
225
+ coords.append([float(ra), float(dec)])
226
+
227
+ radec_polygons.append(Polygon(coords))
228
+
229
+ mp = MultiPolygon(radec_polygons)
230
+ extent = mp.convex_hull
231
+
232
+ # extent = segmentize(extent, max_segment_length=1)
233
+
234
+ print(extent.area)
235
+
236
+ # self.polygon(
237
+ # style__fill_color="red",
238
+ # style__alpha=0.3,
239
+ # geometry=extent
240
+ # )
241
+ # print(extent)
242
+
243
+ return extent
244
+
245
+ def _axes_to_azalt(self, x: float, y: float) -> tuple[float, float]:
246
+ trans = self.ax.transAxes + self.ax.transData.inverted()
247
+ x_projected, y_projected = self.ax.transAxes.inverted().transform((x, y))
248
+ x_projected, y_projected = trans.transform((x, y)) # axes to data
249
+ az, alt = self._crs.transform_point(x_projected, y_projected, self._proj)
250
+ return float(az), float(alt)
251
+
252
+ @profile
253
+ @cache
254
+ def _extent_mask(self):
255
+ coords = []
256
+ azalt = []
257
+
258
+ az0, az1 = int(self.az[0]), int(self.az[1])
259
+ alt0, alt1 = int(self.alt[0]), int(self.alt[1])
260
+
261
+ for az in range(az0, az1, 5):
262
+ for alt in range(alt0, alt1, 5):
263
+ # ax = x / 100
264
+ # ay = y / 100
265
+
266
+ # az, alt = self._axes_to_azalt(ax, ay)
267
+
268
+ if az > 360:
269
+ az -= 360
270
+
271
+ azalt.append([az, alt])
272
+ ra, dec, _ = (
273
+ self.location.at(self.observer.timescale)
274
+ .from_altaz(alt_degrees=alt, az_degrees=az)
275
+ .radec()
276
+ )
277
+ ra = float(ra.hours * 15)
278
+ dec = float(dec.degrees)
279
+
280
+ if dec > 75:
281
+ dec = 90
282
+
283
+ if ra < 180:
284
+ ra += 360
285
+ coords.append([float(ra), float(dec)])
286
+
287
+ # if prev_ra is not None and abs(ra - prev_ra) > 180:
288
+ # current_polygon_coords += [current_polygon_coords[0]]
289
+ # polygon_coords.append(
290
+ # current_polygon_coords
291
+ # )
292
+ # current_polygon_coords = [[ra, dec]]
293
+ # else:
294
+ # current_polygon_coords.append([ra, dec])
295
+
296
+ # prev_ra = ra
297
+
298
+ # if current_polygon_coords:
299
+ # current_polygon_coords += [current_polygon_coords[0]]
300
+ # polygon_coords.append(current_polygon_coords)
301
+ # print(current_polygon_coords)
302
+
303
+ # print(len(polygon_coords))
304
+ from starplot.geometry import split_polygon_at_360
305
+
306
+ # polygons = split_polygon_at_zero(extent)
307
+
308
+ from shapely import convex_hull, MultiPoint
309
+ from pprint import pprint
310
+
311
+ # extent = MultiPolygon([Polygon(c) for c in polygon_coords])
312
+ # extent = Polygon(coords)
313
+ extent = convex_hull(MultiPoint(coords))
314
+ polygons = split_polygon_at_360(extent)
315
+
316
+ pprint(polygons)
317
+
318
+ # extent = extent.convex_hull
319
+ # from shapely import segmentize
320
+ # polygons = [segmentize(p, max_segment_length=1) for p in polygons]
321
+ mpoly = MultiPolygon(polygons)
322
+
323
+ for p in mpoly.geoms:
324
+ self.polygon(style__fill_color="red", style__alpha=0.3, geometry=p)
325
+
326
+ # print(extent)
327
+
328
+ return mpoly
329
+
330
+ def _is_global_extent(self):
331
+ """Returns True if the plot's RA/DEC range is the entire celestial sphere"""
332
+ return all(
333
+ [
334
+ self.ra_min == 0,
335
+ self.ra_max == 360,
336
+ self.dec_min == -90,
337
+ self.dec_max == 90,
338
+ ]
339
+ )
340
+
341
+
59
342
  class CreateMapMixin:
60
343
  def create_map(self, height_degrees: float, width_degrees: float, *args, **kwargs):
61
344
  """
starplot/optic.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from typing import Callable, Mapping
2
2
 
3
- import pandas as pd
3
+ # import pandas as pd
4
4
 
5
5
  from cartopy import crs as ccrs
6
6
  from matplotlib import pyplot as plt, patches, path
@@ -9,12 +9,17 @@ from skyfield.api import wgs84, Star as SkyfieldStar
9
9
  from starplot.coordinates import CoordinateSystem
10
10
  from starplot import callables
11
11
  from starplot.base import BasePlot, DPI
12
- from starplot.data.stars import StarCatalog, STAR_NAMES
12
+ from starplot.data.stars import StarCatalog
13
13
  from starplot.mixins import ExtentMaskMixin
14
14
  from starplot.models import Star
15
15
  from starplot.observer import Observer
16
16
  from starplot.optics import Optic, Camera
17
- from starplot.plotters import StarPlotterMixin, DsoPlotterMixin, GradientBackgroundMixin
17
+ from starplot.plotters import (
18
+ StarPlotterMixin,
19
+ DsoPlotterMixin,
20
+ GradientBackgroundMixin,
21
+ LegendPlotterMixin,
22
+ )
18
23
  from starplot.styles import (
19
24
  PlotStyle,
20
25
  ObjectStyle,
@@ -26,7 +31,7 @@ from starplot.styles import (
26
31
  )
27
32
  from starplot.utils import azimuth_to_string
28
33
 
29
- pd.options.mode.chained_assignment = None # default='warn'
34
+ # pd.options.mode.chained_assignment = None # default='warn'
30
35
 
31
36
  DEFAULT_OPTIC_STYLE = PlotStyle().extend(extensions.OPTIC)
32
37
 
@@ -37,6 +42,7 @@ class OpticPlot(
37
42
  StarPlotterMixin,
38
43
  DsoPlotterMixin,
39
44
  GradientBackgroundMixin,
45
+ LegendPlotterMixin,
40
46
  ):
41
47
  """Creates a new optic plot.
42
48
 
@@ -234,7 +240,8 @@ class OpticPlot(
234
240
  size_fn: Callable[[Star], float] = callables.size_by_magnitude_for_optic,
235
241
  alpha_fn: Callable[[Star], float] = callables.alpha_by_magnitude,
236
242
  color_fn: Callable[[Star], str] = None,
237
- labels: Mapping[int, str] = STAR_NAMES,
243
+ label_fn: Callable[[Star], str] = None,
244
+ labels: Mapping[int, str] = None,
238
245
  legend_label: str = "Star",
239
246
  bayer_labels: bool = False,
240
247
  flamsteed_labels: bool = False,
@@ -245,6 +252,12 @@ class OpticPlot(
245
252
  """
246
253
  Plots stars
247
254
 
255
+ Labels for stars are determined in this order:
256
+
257
+ 1. Return value from `label_fn`
258
+ 2. Value for star's HIP id in `labels`
259
+ 3. IAU-designated name, as listed in the [data reference](/data/star-designations/)
260
+
248
261
  Args:
249
262
  where: A list of expressions that determine which stars to plot. See [Selecting Objects](/reference-selecting-objects/) for details.
250
263
  where_labels: A list of expressions that determine which stars are labeled on the plot. See [Selecting Objects](/reference-selecting-objects/) for details.
@@ -254,7 +267,8 @@ class OpticPlot(
254
267
  size_fn: Callable for calculating the marker size of each star. If `None`, then the marker style's size will be used.
255
268
  alpha_fn: Callable for calculating the alpha value (aka "opacity") of each star. If `None`, then the marker style's alpha will be used.
256
269
  color_fn: Callable for calculating the color of each star. If `None`, then the marker style's color will be used.
257
- 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`.
270
+ label_fn: Callable for determining the label of each star. If `None`, then the names in the `labels` kwarg will be used.
271
+ labels: A dictionary that maps a star's HIP id to the label that'll be plotted for that star. If `None`, then the star's IAU-designated name will be used.
258
272
  legend_label: Label for stars in the legend. If `None`, then they will not be in the legend.
259
273
  bayer_labels: If True, then Bayer labels for stars will be plotted.
260
274
  flamsteed_labels: If True, then Flamsteed number labels for stars will be plotted.
@@ -269,18 +283,20 @@ class OpticPlot(
269
283
  return size_fn(s) * optic_star_multiplier * 0.68
270
284
 
271
285
  super().stars(
286
+ where=where,
287
+ where_labels=where_labels,
272
288
  catalog=catalog,
273
289
  style=style,
274
290
  rasterize=rasterize,
275
291
  size_fn=size_fn_mx,
276
292
  alpha_fn=alpha_fn,
277
293
  color_fn=color_fn,
278
- where=where,
279
- where_labels=where_labels,
294
+ label_fn=label_fn,
280
295
  labels=labels,
281
296
  legend_label=legend_label,
282
297
  bayer_labels=bayer_labels,
283
298
  flamsteed_labels=flamsteed_labels,
299
+ sql=sql,
284
300
  *args,
285
301
  **kwargs,
286
302
  )
@@ -16,7 +16,13 @@ from starplot.data.constellations import (
16
16
  from starplot.data.constellation_stars import CONSTELLATION_HIPS
17
17
  from starplot.models import Star
18
18
  from starplot.models.constellation import from_tuple as constellation_from_tuple
19
- from starplot.projections import Mercator, Miller
19
+ from starplot.projections import (
20
+ StereoNorth,
21
+ StereoSouth,
22
+ Stereographic,
23
+ Equidistant,
24
+ LambertAzEqArea,
25
+ )
20
26
  from starplot.profile import profile
21
27
  from starplot.styles import PathStyle, LineStyle, LabelStyle
22
28
  from starplot.styles.helpers import use_style
@@ -34,6 +40,14 @@ DEFAULT_AUTO_ADJUST_SETTINGS = {
34
40
  }
35
41
  """Default settings for auto-adjusting constellation labels"""
36
42
 
43
+ GEODETIC_PROJECTIONS = (
44
+ Equidistant,
45
+ LambertAzEqArea,
46
+ Stereographic,
47
+ StereoNorth,
48
+ StereoSouth,
49
+ )
50
+
37
51
 
38
52
  class ConstellationPlotterMixin:
39
53
  def inbounds_temp(self, x, y):
@@ -89,10 +103,10 @@ class ConstellationPlotterMixin:
89
103
  return
90
104
 
91
105
  projection = getattr(self, "projection", None)
92
- if isinstance(projection, Mercator) or isinstance(projection, Miller):
93
- transform = self._plate_carree
94
- else:
106
+ if isinstance(projection, GEODETIC_PROJECTIONS):
95
107
  transform = self._geodetic
108
+ else:
109
+ transform = self._plate_carree
96
110
 
97
111
  style_kwargs = style.matplot_kwargs(self.scale)
98
112
  constellation_points_to_index = []
@@ -136,7 +150,7 @@ class ConstellationPlotterMixin:
136
150
  if any([np.isnan(n) for n in start + end]):
137
151
  continue
138
152
 
139
- for x, y in points_on_line(start, end, 25):
153
+ for x, y in points_on_line(start, end, num_points=25):
140
154
  display_x, display_y = self.ax.transData.transform((x, y))
141
155
  if display_x < 0 or display_y < 0:
142
156
  continue
@@ -1,5 +1,3 @@
1
- import geopandas as gpd
2
-
3
1
  from shapely import MultiPolygon
4
2
  from shapely import (
5
3
  MultiPoint,
@@ -20,6 +18,7 @@ class ExperimentalPlotterMixin:
20
18
  def _constellation_borders(self):
21
19
  from shapely import LineString, MultiLineString
22
20
  from shapely.ops import unary_union
21
+ import geopandas as gpd
23
22
 
24
23
  constellation_borders = gpd.read_file(
25
24
  DataFiles.CONSTELLATIONS,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: starplot
3
- Version: 0.16.3
3
+ Version: 0.16.5
4
4
  Summary: Star charts and maps of the sky
5
5
  Keywords: astronomy,stars,charts,maps,constellations,sky,plotting
6
6
  Author-email: Steve Berardi <hello@steveberardi.com>
@@ -15,7 +15,6 @@ Requires-Dist: matplotlib >= 3.8.0
15
15
  Requires-Dist: numpy >= 1.26.2
16
16
  Requires-Dist: pandas >= 1.4.0
17
17
  Requires-Dist: pydantic >= 2.10.6
18
- Requires-Dist: pydantic-settings >= 2.10.1
19
18
  Requires-Dist: shapely >= 2.0.1
20
19
  Requires-Dist: skyfield >= 1.41
21
20
  Requires-Dist: cartopy >= 0.21.1
@@ -104,11 +103,11 @@ For a demo of Starplot's zenith plots, check out:
104
103
 
105
104
  [Sky Atlas - Star Chart Creator](https://skyatlas.app/star-charts/)
106
105
 
107
- ## Discord
106
+ ## Getting Help + Updates
108
107
 
109
- Chat with other starplotters on our Discord server:
110
-
111
- https://discord.gg/WewJJjshFu
108
+ - Chat with other starplotters on our [Discord server](https://discord.gg/WewJJjshFu)
109
+ - [Follow us on Bluesky](https://bsky.app/profile/starplot.dev)
110
+ - [Join our newsletter](https://buttondown.com/starplot)
112
111
 
113
112
  ## Contributing
114
113
 
@@ -1,16 +1,16 @@
1
- starplot/__init__.py,sha256=uOn02qtp3L8uit-aiNVqZnFDz0s8bju88h9_bUdgbgk,726
1
+ starplot/__init__.py,sha256=5IOFDncHNPC1ZfC1ccAPasARRVjseJghixBh45PhNfE,726
2
2
  starplot/base.py,sha256=o8IEYvpRj_79atDlNrxblotVlgIt4pRBXzVADUzgtY0,43166
3
3
  starplot/callables.py,sha256=_zDGCAJTqqNLvCtcIt4PVEe2L0Ggvl6pj-7ZFI-0zqI,4043
4
4
  starplot/cli.py,sha256=ZcOtEAzwX7pLtLHxwDhIVb8sStZjSZr9Er9vJ4cc1J4,718
5
- starplot/config.py,sha256=p8zXKQWxlPJPr9L3jQp_zQE2591Zrm1g4IRrw-QUk4c,1810
5
+ starplot/config.py,sha256=GoyCvYqle-eRD83cFkpttAUj6PUTBTFoD3yKMmIQpRk,2100
6
6
  starplot/coordinates.py,sha256=7LDz32VTKa8H-4F67-XvzmjpcTVojZwYVJzXZkBaZ3U,136
7
7
  starplot/geod.py,sha256=pVnDr-yxGjOIXwKCknbtCZiRle5IqRnqpY43s0PMnmA,2574
8
- starplot/geometry.py,sha256=e9YupWEWJmUT_FywTLEvk3RUzksmbTcR5p5b6VQ3uF4,5575
9
- starplot/horizon.py,sha256=-pdbJZ26Izp5VsCaxIgZNvms_pXtMSVN8AOOKzprx_c,19839
10
- starplot/map.py,sha256=0ZSHZEb1f9KaWTLe1cGMwf0mtaghrQJO9C0PsbLJKeU,19241
11
- starplot/mixins.py,sha256=n_Ei0COGdMW1P1herJSya_6afqJ13n-fmoyJ_f_Bpqk,3372
8
+ starplot/geometry.py,sha256=eNrSZX-axBpGEGVnmMeIHgpf7qTiZPVKtg85SkzK1yU,6630
9
+ starplot/horizon.py,sha256=XCp6eNmzodvqKEl9BL3SLWudCN_D4V7sthhUuVE6xio,20022
10
+ starplot/map.py,sha256=mU5oD-JQ9IbEvfdReeT3sdwsYOoqzeFMxa_Rd-6_cjY,19137
11
+ starplot/mixins.py,sha256=ZZBVg1Ad3xnbyLskCEhpDcd9Jmb_2_jT8hUiiCbU658,12268
12
12
  starplot/observer.py,sha256=R15X0DZhDSFQ06mf4Tv-q7Qf-o1GR3CSz-9H_CBDFg8,1825
13
- starplot/optic.py,sha256=dzVlinYdnnNMOzmJmt58_nonEjDjf3-i5yppqMy522I,16682
13
+ starplot/optic.py,sha256=U3gAzc236pD47ZDpQ2fsZJY-bn-vdMI-H86CKBGsNDY,17201
14
14
  starplot/optics.py,sha256=v94Ff8bIruVBrME7lzwORlayadpoFIGQsAK0sFlx43Y,9314
15
15
  starplot/profile.py,sha256=V5LOZFDdnGo-P8ikWvV3jmUVJIKO3gd4H2bjBlk7aUM,300
16
16
  starplot/projections.py,sha256=6mj8uJkWE-79giXF-OVS8ixUbbojOHuwI51C-ovHyIo,5101
@@ -18,18 +18,18 @@ starplot/utils.py,sha256=49m8QXJl188Pgpef_82gyykly7ZjfAuHVEcSA5QFITA,3720
18
18
  starplot/warnings.py,sha256=uKvGSAVpWKZIHMKxxegO5owFJnKvBYLyq3pJatD0qQ4,594
19
19
  starplot/zenith.py,sha256=Hb_Dq4-xVIIGc1iCmtdFoOLbPX1BL9LKQ3T7TcilqmQ,6557
20
20
  starplot/data/__init__.py,sha256=caxXwutqzBf9XeVMuiK_R-RaM-Tfqbj-sKcHergsPOw,299
21
- starplot/data/bigsky.py,sha256=3Tb_WI_6mSQVD5x1JFg1CXQoJRFBbfRLTrp36SyY1XM,2827
21
+ starplot/data/bigsky.py,sha256=-LAS8OHGj2FwpaRxlfhIRlOUV9WwXQgJuIJQyfY9d4Q,2831
22
22
  starplot/data/constellation_lines.py,sha256=RLyFSoxGRL7kj9gGT4DDUubClKZEDu5wGUMG3PlpYfY,19344
23
23
  starplot/data/constellation_stars.py,sha256=l2GeyJWuVtzH-MIw1oGR6jeMBvfqX-q-S2V_ilcEZG8,38221
24
- starplot/data/constellations.py,sha256=05fjaLy5gBDQYyxMV_Etq2O2OMzOh0ozYWT_BwNmfMc,15745
25
- starplot/data/db.py,sha256=UFzjyWL5U1yDf6dIPyS_FLy3WUltHT-7lhVljTyOLuc,391
26
- starplot/data/dsos.py,sha256=Tc264aSA3J8eVmVTUhjrMYMkijP870dqaleMk7xr3hE,1509
24
+ starplot/data/constellations.py,sha256=uSPBnste3NKXUn_7g7g16rcFNhTmP38AKaxmVHwzos4,15730
25
+ starplot/data/db.py,sha256=bus3I-3LA-tYRnVASZ0ar_UeFEdEuqCxdMDowLRTu2g,398
26
+ starplot/data/dsos.py,sha256=Hfnsa2Tz9gfgCMu8SRuN5hEwKXz9u56AbTLH4rNFOaI,1504
27
27
  starplot/data/ecliptic.py,sha256=Qre9YdFbTC9mAx-vd2C0Ou4CsnRehIScnTpmEUDDYcM,4638
28
- starplot/data/stars.py,sha256=ImcD0lwGgnOlVICQyM62nXVHoSvkS82x1TNIldFprCU,12288
28
+ starplot/data/stars.py,sha256=x22ayry_r1dNwR4GFKU3GuIB1VKG_LJGQUTltKfqILI,2759
29
29
  starplot/data/utils.py,sha256=RPk3bnfL-KtjMk1VQygDD27INz_gEya_B1hu7X4K8hU,772
30
30
  starplot/data/library/bigsky.0.4.0.stars.mag11.parquet,sha256=l1whWt41bkXslqVF2n7qeFrvja3sqO8pbPJaNqTnECE,38883485
31
31
  starplot/data/library/de421_2001.bsp,sha256=ymkZigAd8Vgscq_DYkdR4nZ1VGD5wwPd-sxe6HiiTns,5341104
32
- starplot/data/library/sky.db,sha256=eFfYEIX88xmHDW0PsGtyJVyOArAHccKLR2-T9E65ClI,38023168
32
+ starplot/data/library/sky.db,sha256=Xx43RwVEbQ0J_cSBLUJ5E9SmQiBXjH5nruuhpyK4WnE,38023168
33
33
  starplot/models/__init__.py,sha256=qi4arVatzEcR9TAbHadSbhq8xRhSb1_Br3UKNv4FP7o,330
34
34
  starplot/models/base.py,sha256=sQ_qTUOUfGxtgLdJVnSbMG328_d_AO5GSIcnC-e0m80,2681
35
35
  starplot/models/constellation.py,sha256=ayIGfafFs2eymWHlFdDgZPJkx115x_avPC1egqVZWnI,3220
@@ -40,9 +40,9 @@ starplot/models/planet.py,sha256=TyPGMQnlq4NwMXNSRrIgbpL4rAWTdKyNeo5jpSR0Crg,466
40
40
  starplot/models/star.py,sha256=gw36P1BB9qq4IfvS4TqcZsmltKeNWvcnw87wSDxmE1w,4555
41
41
  starplot/models/sun.py,sha256=3EaRJclmYX-jhSJav5nGCazH-9_YHT6Qr2irDSsC63I,2342
42
42
  starplot/plotters/__init__.py,sha256=qxfzgsrOxu3Xvuh7Ucbq_ZFWvohbc4iGqOCEBFZ31oo,337
43
- starplot/plotters/constellations.py,sha256=3aGFbxBewYb6Ex5pBPjGsVgBbO59aEmNhaOt8E2JyXg,13290
43
+ starplot/plotters/constellations.py,sha256=QfNk6Zv61NR5XmpK8bGXTHhfST5J2pXPqfdnI3BNSyE,13476
44
44
  starplot/plotters/dsos.py,sha256=HxURv4a0UZyT9tp8vbLUXbx6ZyX5AUz5cSajV3A8G4Y,9146
45
- starplot/plotters/experimental.py,sha256=P4T9jJyAnViv6k2RJpmYEY8uI-0dyd-E6NeIRUWbu6c,5909
45
+ starplot/plotters/experimental.py,sha256=XtWtyoiPmR2heVGcoMM6zOMQ0uAQzGYpg-E6-mRgKI8,5916
46
46
  starplot/plotters/gradients.py,sha256=ZonNeIEmbcZZWjFtlPahGtGCgeTCeimp84PZnqj8dXY,5781
47
47
  starplot/plotters/legend.py,sha256=RMdAL1t1PcfYzcizkHl_lksK2Ql-BDALNdxz2bXgyew,8573
48
48
  starplot/plotters/milkyway.py,sha256=WpWwHefSHE2bDI_vTve-tbma31kk1CIGOp1ukLy-BiE,1189
@@ -98,8 +98,8 @@ starplot/styles/fonts-library/inter/Inter-SemiBoldItalic.ttf,sha256=HhKJRT16iVz7
98
98
  starplot/styles/fonts-library/inter/Inter-Thin.ttf,sha256=TDktzIrZFvD533VZq1VjsB3ZT587LbNGF_45LgAGAzk,403404
99
99
  starplot/styles/fonts-library/inter/Inter-ThinItalic.ttf,sha256=X8Ca-UpEf65vgsAPFd-u-ernxWDmy-RtPoRSQBmldKo,410232
100
100
  starplot/styles/fonts-library/inter/LICENSE.txt,sha256=JiSB6ERSGzJvXs0FPlm5jIstp4yO4b27boF0MF5Uk1o,4380
101
- starplot-0.16.3.dist-info/entry_points.txt,sha256=Sm6jC6h_RcaMGC8saLnYmT0SdhcF9_rMeQIiHneLHyc,46
102
- starplot-0.16.3.dist-info/licenses/LICENSE,sha256=jcjClHF4BQwhz-kDgia-KphO9Zxu0rCa2BbiA7j1jeU,1070
103
- starplot-0.16.3.dist-info/WHEEL,sha256=Dyt6SBfaasWElUrURkknVFAZDHSTwxg3PaTza7RSbkY,100
104
- starplot-0.16.3.dist-info/METADATA,sha256=IHjgi0WL5ROBg3mRjTqTFnLNV0f2a-QNW8u7tMTXWKE,4379
105
- starplot-0.16.3.dist-info/RECORD,,
101
+ starplot-0.16.5.dist-info/entry_points.txt,sha256=Sm6jC6h_RcaMGC8saLnYmT0SdhcF9_rMeQIiHneLHyc,46
102
+ starplot-0.16.5.dist-info/licenses/LICENSE,sha256=jcjClHF4BQwhz-kDgia-KphO9Zxu0rCa2BbiA7j1jeU,1070
103
+ starplot-0.16.5.dist-info/WHEEL,sha256=Dyt6SBfaasWElUrURkknVFAZDHSTwxg3PaTza7RSbkY,100
104
+ starplot-0.16.5.dist-info/METADATA,sha256=0aHdYJkfpjQNKspYwNW99pIf4hqzkGo0n1V2K_33vZs,4475
105
+ starplot-0.16.5.dist-info/RECORD,,