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/horizon.py
CHANGED
|
@@ -1,30 +1,33 @@
|
|
|
1
1
|
import math
|
|
2
2
|
|
|
3
|
-
from datetime import datetime
|
|
4
3
|
from functools import cache
|
|
4
|
+
from typing import Callable
|
|
5
5
|
|
|
6
6
|
import pandas as pd
|
|
7
7
|
import geopandas as gpd
|
|
8
8
|
|
|
9
9
|
from cartopy import crs as ccrs
|
|
10
10
|
from matplotlib import pyplot as plt, patches
|
|
11
|
-
from matplotlib.ticker import FixedLocator
|
|
11
|
+
from matplotlib.ticker import FixedLocator, FuncFormatter
|
|
12
12
|
from skyfield.api import wgs84, Star as SkyfieldStar
|
|
13
|
-
from shapely import Point
|
|
13
|
+
from shapely import Point, Polygon, MultiPolygon
|
|
14
14
|
from starplot.coordinates import CoordinateSystem
|
|
15
15
|
from starplot.base import BasePlot, DPI
|
|
16
16
|
from starplot.mixins import ExtentMaskMixin
|
|
17
|
+
from starplot.observer import Observer
|
|
17
18
|
from starplot.plotters import (
|
|
18
19
|
ConstellationPlotterMixin,
|
|
19
20
|
StarPlotterMixin,
|
|
20
21
|
DsoPlotterMixin,
|
|
21
22
|
MilkyWayPlotterMixin,
|
|
23
|
+
GradientBackgroundMixin,
|
|
22
24
|
)
|
|
23
25
|
from starplot.styles import (
|
|
24
26
|
PlotStyle,
|
|
25
27
|
extensions,
|
|
26
28
|
use_style,
|
|
27
29
|
PathStyle,
|
|
30
|
+
GradientDirection,
|
|
28
31
|
)
|
|
29
32
|
|
|
30
33
|
pd.options.mode.chained_assignment = None # default='warn'
|
|
@@ -50,6 +53,7 @@ class HorizonPlot(
|
|
|
50
53
|
StarPlotterMixin,
|
|
51
54
|
DsoPlotterMixin,
|
|
52
55
|
MilkyWayPlotterMixin,
|
|
56
|
+
GradientBackgroundMixin,
|
|
53
57
|
):
|
|
54
58
|
"""Creates a new horizon plot.
|
|
55
59
|
|
|
@@ -73,16 +77,15 @@ class HorizonPlot(
|
|
|
73
77
|
"""
|
|
74
78
|
|
|
75
79
|
_coordinate_system = CoordinateSystem.AZ_ALT
|
|
80
|
+
_gradient_direction = GradientDirection.LINEAR
|
|
76
81
|
|
|
77
82
|
FIELD_OF_VIEW_MAX = 9.0
|
|
78
83
|
|
|
79
84
|
def __init__(
|
|
80
85
|
self,
|
|
81
|
-
lat: float,
|
|
82
|
-
lon: float,
|
|
83
86
|
altitude: tuple[float, float],
|
|
84
87
|
azimuth: tuple[float, float],
|
|
85
|
-
|
|
88
|
+
observer: Observer = Observer(),
|
|
86
89
|
ephemeris: str = "de421_2001.bsp",
|
|
87
90
|
style: PlotStyle = DEFAULT_HORIZON_STYLE,
|
|
88
91
|
resolution: int = 4096,
|
|
@@ -94,7 +97,7 @@ class HorizonPlot(
|
|
|
94
97
|
**kwargs,
|
|
95
98
|
) -> "HorizonPlot":
|
|
96
99
|
super().__init__(
|
|
97
|
-
|
|
100
|
+
observer,
|
|
98
101
|
ephemeris,
|
|
99
102
|
style,
|
|
100
103
|
resolution,
|
|
@@ -121,8 +124,6 @@ class HorizonPlot(
|
|
|
121
124
|
self.az = azimuth
|
|
122
125
|
self.center_alt = sum(altitude) / 2
|
|
123
126
|
self.center_az = sum(azimuth) / 2
|
|
124
|
-
self.lat = lat
|
|
125
|
-
self.lon = lon
|
|
126
127
|
|
|
127
128
|
self._geodetic = ccrs.Geodetic()
|
|
128
129
|
self._plate_carree = ccrs.PlateCarree()
|
|
@@ -204,8 +205,8 @@ class HorizonPlot(
|
|
|
204
205
|
|
|
205
206
|
def _calc_position(self):
|
|
206
207
|
earth = self.ephemeris["earth"]
|
|
207
|
-
self.location = earth + wgs84.latlon(self.lat, self.lon)
|
|
208
|
-
self.observe = self.location.at(self.timescale).observe
|
|
208
|
+
self.location = earth + wgs84.latlon(self.observer.lat, self.observer.lon)
|
|
209
|
+
self.observe = self.location.at(self.observer.timescale).observe
|
|
209
210
|
|
|
210
211
|
# locations = [
|
|
211
212
|
# self.location.at(self.timescale).from_altaz(
|
|
@@ -260,36 +261,85 @@ class HorizonPlot(
|
|
|
260
261
|
|
|
261
262
|
self.ra_min = 0
|
|
262
263
|
self.ra_max = 360
|
|
263
|
-
self.dec_min = self.lat - 90
|
|
264
|
-
self.dec_max = self.lat + 90
|
|
264
|
+
self.dec_min = self.observer.lat - 90
|
|
265
|
+
self.dec_max = self.observer.lat + 90
|
|
265
266
|
|
|
266
267
|
self.logger.debug(
|
|
267
268
|
f"Extent = RA ({self.ra_min:.2f}, {self.ra_max:.2f}) DEC ({self.dec_min:.2f}, {self.dec_max:.2f})"
|
|
268
269
|
)
|
|
269
270
|
|
|
270
|
-
|
|
271
|
-
|
|
271
|
+
@cache
|
|
272
|
+
def _extent_mask_altaz(self):
|
|
273
|
+
"""
|
|
274
|
+
Returns shapely geometry objects of the alt/az extent
|
|
275
|
+
|
|
276
|
+
If the extent crosses North cardinal direction, then a MultiPolygon will be returned
|
|
277
|
+
"""
|
|
272
278
|
extent = list(self.ax.get_extent(crs=self._plate_carree))
|
|
273
|
-
|
|
279
|
+
alt_min, alt_max = extent[2], extent[3]
|
|
280
|
+
az_min, az_max = extent[0], extent[1]
|
|
274
281
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if extent[1] < 0:
|
|
278
|
-
extent[1] += 180
|
|
282
|
+
az_ul, _ = self._ax_to_azalt(0, 1)
|
|
283
|
+
az_ur, _ = self._ax_to_azalt(1, 1)
|
|
279
284
|
|
|
280
|
-
|
|
285
|
+
if az_ul < 0:
|
|
286
|
+
az_ul += 360
|
|
281
287
|
|
|
282
|
-
|
|
288
|
+
if az_ur < 0:
|
|
289
|
+
az_ur += 360
|
|
290
|
+
|
|
291
|
+
az_min = min(self.az[0], self.az[1], az_ul, az_ur)
|
|
292
|
+
az_max = max(self.az[0], self.az[1], az_ul, az_ur)
|
|
293
|
+
|
|
294
|
+
if az_min < 0:
|
|
295
|
+
az_min += 360
|
|
296
|
+
if az_max < 0:
|
|
297
|
+
az_max += 360
|
|
298
|
+
|
|
299
|
+
if az_min >= az_max:
|
|
300
|
+
az_max += 360
|
|
301
|
+
|
|
302
|
+
self.az = (az_min, az_max)
|
|
303
|
+
self.alt = (alt_min, alt_max)
|
|
304
|
+
|
|
305
|
+
if az_max <= 360:
|
|
306
|
+
coords = [
|
|
307
|
+
[az_min, alt_min],
|
|
308
|
+
[az_max, alt_min],
|
|
309
|
+
[az_max, alt_max],
|
|
310
|
+
[az_min, alt_max],
|
|
311
|
+
[az_min, alt_min],
|
|
312
|
+
]
|
|
313
|
+
return Polygon(coords)
|
|
314
|
+
|
|
315
|
+
else:
|
|
316
|
+
coords_1 = [
|
|
317
|
+
[az_min, alt_min],
|
|
318
|
+
[360, alt_min],
|
|
319
|
+
[360, alt_max],
|
|
320
|
+
[az_min, alt_max],
|
|
321
|
+
[az_min, alt_min],
|
|
322
|
+
]
|
|
323
|
+
coords_2 = [
|
|
324
|
+
[0, alt_min],
|
|
325
|
+
[az_max - 360, alt_min],
|
|
326
|
+
[az_max - 360, alt_max],
|
|
327
|
+
[0, alt_max],
|
|
328
|
+
[0, alt_min],
|
|
329
|
+
]
|
|
330
|
+
|
|
331
|
+
return MultiPolygon(
|
|
332
|
+
[
|
|
333
|
+
Polygon(coords_1),
|
|
334
|
+
Polygon(coords_2),
|
|
335
|
+
]
|
|
336
|
+
)
|
|
283
337
|
|
|
284
338
|
@use_style(PathStyle, "horizon")
|
|
285
339
|
def horizon(
|
|
286
340
|
self,
|
|
287
341
|
style: PathStyle = None,
|
|
288
342
|
labels: dict[int, str] = DEFAULT_HORIZON_LABELS,
|
|
289
|
-
show_degree_labels: bool = True,
|
|
290
|
-
degree_step: int = 15,
|
|
291
|
-
show_ticks: bool = True,
|
|
292
|
-
tick_step: int = 5,
|
|
293
343
|
):
|
|
294
344
|
"""
|
|
295
345
|
Plots rectangle for horizon that shows cardinal directions and azimuth labels.
|
|
@@ -297,24 +347,15 @@ class HorizonPlot(
|
|
|
297
347
|
Args:
|
|
298
348
|
style: Style of the horizon path. If None, then the plot's style definition will be used.
|
|
299
349
|
labels: Dictionary that maps azimuth values (0...360) to their cardinal direction labels (e.g. "N"). Default is to label each 45deg direction (e.g. "N", "NE", "E", etc)
|
|
300
|
-
show_degree_labels: If True, then azimuth degree labels will be plotted on the horizon path
|
|
301
|
-
degree_step: Step size for degree labels
|
|
302
|
-
show_ticks: If True, then tick marks will be plotted on the horizon path for every `tick_step` degree that is not also a degree label
|
|
303
|
-
tick_step: Step size for tick marks
|
|
304
350
|
"""
|
|
305
|
-
|
|
306
|
-
if show_degree_labels or show_ticks:
|
|
307
|
-
patch_y = -0.11 * self.scale
|
|
308
|
-
else:
|
|
309
|
-
patch_y = -0.08 * self.scale
|
|
310
|
-
|
|
351
|
+
patch_y = -0.11 * self.scale
|
|
311
352
|
bottom = patches.Polygon(
|
|
312
353
|
[
|
|
313
|
-
(0, 0),
|
|
314
|
-
(1, 0),
|
|
354
|
+
(0, -0.04 * self.scale),
|
|
355
|
+
(1, -0.04 * self.scale),
|
|
315
356
|
(1, patch_y),
|
|
316
357
|
(0, patch_y),
|
|
317
|
-
(0, 0),
|
|
358
|
+
(0, -0.04 * self.scale),
|
|
318
359
|
],
|
|
319
360
|
color=style.line.color.as_hex(),
|
|
320
361
|
transform=self.ax.transAxes,
|
|
@@ -322,92 +363,137 @@ class HorizonPlot(
|
|
|
322
363
|
)
|
|
323
364
|
self.ax.add_patch(bottom)
|
|
324
365
|
|
|
325
|
-
|
|
326
|
-
return self._to_ax(d, self.alt[0])[0]
|
|
327
|
-
|
|
328
|
-
for az in range(int(self.az[0]), int(self.az[1]), 1):
|
|
366
|
+
for az, label in labels.items():
|
|
329
367
|
az = int(az)
|
|
330
|
-
|
|
331
|
-
if az >= 360:
|
|
332
|
-
az -= 360
|
|
333
|
-
|
|
334
|
-
x = az_to_ax(az)
|
|
335
|
-
|
|
368
|
+
x, _ = self._to_ax(az, self.alt[0])
|
|
336
369
|
if x <= 0.03 or x >= 0.97 or math.isnan(x):
|
|
337
370
|
continue
|
|
338
371
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
**style.label.matplot_kwargs(self.scale),
|
|
345
|
-
clip_on=True,
|
|
346
|
-
)
|
|
347
|
-
|
|
348
|
-
if show_degree_labels and az % degree_step == 0:
|
|
349
|
-
self.ax.annotate(
|
|
350
|
-
str(az) + "\u00b0",
|
|
351
|
-
(x, -0.011 * self.scale),
|
|
352
|
-
xycoords=self.ax.transAxes,
|
|
353
|
-
**self.style.gridlines.label.matplot_kwargs(self.scale),
|
|
354
|
-
clip_on=True,
|
|
355
|
-
)
|
|
356
|
-
|
|
357
|
-
elif show_ticks and az % tick_step == 0:
|
|
358
|
-
self.ax.annotate(
|
|
359
|
-
"|",
|
|
360
|
-
(x, -0.011 * self.scale),
|
|
361
|
-
xycoords=self.ax.transAxes,
|
|
362
|
-
**self.style.gridlines.label.matplot_kwargs(self.scale / 2),
|
|
363
|
-
clip_on=True,
|
|
364
|
-
)
|
|
365
|
-
|
|
366
|
-
if show_degree_labels or show_ticks:
|
|
367
|
-
self.ax.plot(
|
|
368
|
-
[0, 1],
|
|
369
|
-
[-0.04 * self.scale, -0.04 * self.scale],
|
|
370
|
-
lw=1,
|
|
371
|
-
color=style.label.font_color.as_hex(),
|
|
372
|
+
self.ax.annotate(
|
|
373
|
+
label,
|
|
374
|
+
(x, patch_y + 0.027),
|
|
375
|
+
xycoords=self.ax.transAxes,
|
|
376
|
+
**style.label.matplot_kwargs(self.scale),
|
|
372
377
|
clip_on=False,
|
|
373
|
-
transform=self.ax.transAxes,
|
|
374
378
|
)
|
|
375
379
|
|
|
376
380
|
@use_style(PathStyle, "gridlines")
|
|
377
381
|
def gridlines(
|
|
378
382
|
self,
|
|
379
383
|
style: PathStyle = None,
|
|
384
|
+
show_labels: list = ["left", "right", "bottom"],
|
|
380
385
|
az_locations: list[float] = None,
|
|
381
386
|
alt_locations: list[float] = None,
|
|
387
|
+
az_formatter_fn: Callable[[float], str] = None,
|
|
388
|
+
alt_formatter_fn: Callable[[float], str] = None,
|
|
389
|
+
divider_line: bool = True,
|
|
390
|
+
show_ticks: bool = True,
|
|
391
|
+
tick_step: int = 5,
|
|
382
392
|
):
|
|
383
393
|
"""
|
|
384
394
|
Plots gridlines
|
|
385
395
|
|
|
386
396
|
Args:
|
|
387
397
|
style: Styling of the gridlines. If None, then the plot's style (specified when creating the plot) will be used
|
|
398
|
+
show_labels: List of locations where labels should be shown (options: "left", "right", "top", "bottom")
|
|
388
399
|
az_locations: List of azimuth locations for the gridlines (in degrees, 0...360). Defaults to every 15 degrees
|
|
389
400
|
alt_locations: List of altitude locations for the gridlines (in degrees, -90...90). Defaults to every 10 degrees.
|
|
390
|
-
|
|
401
|
+
az_formatter_fn: Callable for creating labels of azimuth gridlines
|
|
402
|
+
alt_formatter_fn: Callable for creating labels of altitude gridlines
|
|
403
|
+
divider_line: If True, then a divider line will be plotted below the azimuth labels on the bottom of the plot (this is helpful when also plotting the horizon)
|
|
404
|
+
show_ticks: If True, then tick marks will be plotted on the horizon path for every `tick_step` degree that is not also a degree label
|
|
405
|
+
tick_step: Step size for tick marks
|
|
391
406
|
"""
|
|
407
|
+
az_formatter_fn_default = lambda az: f"{round(az)}\u00b0 " # noqa: E731
|
|
408
|
+
alt_formatter_fn_default = lambda alt: f"{round(alt)}\u00b0 " # noqa: E731
|
|
409
|
+
|
|
410
|
+
az_formatter_fn = az_formatter_fn or az_formatter_fn_default
|
|
411
|
+
alt_formatter_fn = alt_formatter_fn or alt_formatter_fn_default
|
|
412
|
+
|
|
413
|
+
def az_formatter(x, pos) -> str:
|
|
414
|
+
if x < 0:
|
|
415
|
+
x += 360
|
|
416
|
+
return az_formatter_fn(x)
|
|
417
|
+
|
|
418
|
+
def alt_formatter(x, pos) -> str:
|
|
419
|
+
return alt_formatter_fn(x)
|
|
420
|
+
|
|
392
421
|
x_locations = az_locations or [x for x in range(0, 360, 15)]
|
|
393
422
|
x_locations = [x - 180 for x in x_locations]
|
|
394
423
|
y_locations = alt_locations or [d for d in range(-90, 90, 10)]
|
|
395
424
|
|
|
425
|
+
label_style_kwargs = style.label.matplot_kwargs()
|
|
426
|
+
label_style_kwargs.pop("va")
|
|
427
|
+
label_style_kwargs.pop("ha")
|
|
428
|
+
|
|
396
429
|
line_style_kwargs = style.line.matplot_kwargs()
|
|
430
|
+
|
|
397
431
|
gridlines = self.ax.gridlines(
|
|
398
|
-
draw_labels=
|
|
432
|
+
draw_labels=show_labels,
|
|
399
433
|
x_inline=False,
|
|
400
434
|
y_inline=False,
|
|
401
435
|
rotate_labels=False,
|
|
402
436
|
xpadding=12,
|
|
403
437
|
ypadding=12,
|
|
404
|
-
clip_on=True,
|
|
405
|
-
clip_path=self._background_clip_path,
|
|
406
438
|
gid="gridlines",
|
|
439
|
+
xlocs=FixedLocator(x_locations),
|
|
440
|
+
xformatter=FuncFormatter(az_formatter),
|
|
441
|
+
xlabel_style=label_style_kwargs,
|
|
442
|
+
ylocs=FixedLocator(y_locations),
|
|
443
|
+
ylabel_style=label_style_kwargs,
|
|
444
|
+
yformatter=FuncFormatter(alt_formatter),
|
|
407
445
|
**line_style_kwargs,
|
|
408
446
|
)
|
|
409
|
-
gridlines.
|
|
410
|
-
|
|
447
|
+
gridlines.set_zorder(style.line.zorder)
|
|
448
|
+
|
|
449
|
+
if show_labels:
|
|
450
|
+
self._axis_labels = True
|
|
451
|
+
|
|
452
|
+
# gridlines.xlocator = FixedLocator(x_locations)
|
|
453
|
+
# gridlines.xformatter = FuncFormatter(az_formatter)
|
|
454
|
+
# gridlines.xlabel_style = label_style_kwargs
|
|
455
|
+
|
|
456
|
+
# gridlines.ylocator = FixedLocator(y_locations)
|
|
457
|
+
# gridlines.yformatter = FuncFormatter(alt_formatter)
|
|
458
|
+
# gridlines.ylabel_style = label_style_kwargs
|
|
459
|
+
# print(gridlines.label_artists)
|
|
460
|
+
# for label in gridlines.label_artists:
|
|
461
|
+
# label.set_zorder(style.label.zorder)
|
|
462
|
+
|
|
463
|
+
if divider_line:
|
|
464
|
+
self.ax.plot(
|
|
465
|
+
[0, 1],
|
|
466
|
+
[-0.04 * self.scale, -0.04 * self.scale],
|
|
467
|
+
lw=1,
|
|
468
|
+
color=style.label.font_color.as_hex(),
|
|
469
|
+
clip_on=False,
|
|
470
|
+
transform=self.ax.transAxes,
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
if not show_ticks or len(x_locations) < 2:
|
|
474
|
+
return
|
|
475
|
+
|
|
476
|
+
# sort x locations so we iterate in order
|
|
477
|
+
x_locations_sorted = sorted(x_locations)
|
|
478
|
+
for i, az in enumerate(x_locations_sorted[1:], start=1):
|
|
479
|
+
prev_az = x_locations_sorted[i - 1]
|
|
480
|
+
|
|
481
|
+
# start at az label location + tick step cause we only want ticks between labels
|
|
482
|
+
for az_tick in range(prev_az + tick_step, az, tick_step):
|
|
483
|
+
a = int(az_tick)
|
|
484
|
+
if a >= 360:
|
|
485
|
+
a -= 360
|
|
486
|
+
x, _ = self._to_ax(a, self.alt[0])
|
|
487
|
+
|
|
488
|
+
if x <= 0.03 or x >= 0.97 or math.isnan(x):
|
|
489
|
+
continue
|
|
490
|
+
|
|
491
|
+
self.ax.annotate(
|
|
492
|
+
"|",
|
|
493
|
+
(x, -0.011 * self.scale),
|
|
494
|
+
xycoords=self.ax.transAxes,
|
|
495
|
+
**self.style.gridlines.label.matplot_kwargs(self.scale / 2),
|
|
496
|
+
)
|
|
411
497
|
|
|
412
498
|
@cache
|
|
413
499
|
def _to_ax(self, az: float, alt: float) -> tuple[float, float]:
|
|
@@ -417,6 +503,13 @@ class HorizonPlot(
|
|
|
417
503
|
x_axes, y_axes = data_to_axes.transform((x, y))
|
|
418
504
|
return x_axes, y_axes
|
|
419
505
|
|
|
506
|
+
@cache
|
|
507
|
+
def _ax_to_azalt(self, x: float, y: float) -> tuple[float, float]:
|
|
508
|
+
trans = self.ax.transAxes + self.ax.transData.inverted()
|
|
509
|
+
x_projected, y_projected = trans.transform((x, y)) # axes to data
|
|
510
|
+
az, alt = self._crs.transform_point(x_projected, y_projected, self._proj)
|
|
511
|
+
return float(az), float(alt)
|
|
512
|
+
|
|
420
513
|
def _fit_to_ax(self) -> None:
|
|
421
514
|
bbox = self.ax.get_window_extent().transformed(
|
|
422
515
|
self.fig.dpi_scale_trans.inverted()
|
|
@@ -425,16 +518,23 @@ class HorizonPlot(
|
|
|
425
518
|
self.fig.set_size_inches(width, height)
|
|
426
519
|
|
|
427
520
|
def _plot_background_clip_path(self):
|
|
521
|
+
if self.style.has_gradient_background():
|
|
522
|
+
background_color = "#ffffff00"
|
|
523
|
+
self._plot_gradient_background(self.style.background_color)
|
|
524
|
+
else:
|
|
525
|
+
background_color = self.style.background_color.as_hex()
|
|
526
|
+
|
|
428
527
|
self._background_clip_path = patches.Rectangle(
|
|
429
528
|
(0, 0),
|
|
430
529
|
width=1,
|
|
431
530
|
height=1,
|
|
432
|
-
facecolor=
|
|
531
|
+
facecolor=background_color,
|
|
433
532
|
linewidth=0,
|
|
434
533
|
fill=True,
|
|
435
534
|
zorder=-3_000,
|
|
436
535
|
transform=self.ax.transAxes,
|
|
437
536
|
)
|
|
537
|
+
self.ax.set_facecolor(background_color)
|
|
438
538
|
|
|
439
539
|
self.ax.add_patch(self._background_clip_path)
|
|
440
540
|
self._update_clip_path_polygon()
|
|
@@ -466,4 +566,8 @@ class HorizonPlot(
|
|
|
466
566
|
self.ax.set_extent(bounds, crs=ccrs.PlateCarree())
|
|
467
567
|
|
|
468
568
|
self._fit_to_ax()
|
|
569
|
+
|
|
570
|
+
# if self.gradient_preset:
|
|
571
|
+
# self.apply_gradient_background(self.gradient_preset)
|
|
572
|
+
|
|
469
573
|
self._plot_background_clip_path()
|