Skip to content

Commit 625b0c0

Browse files
authored
Merge pull request #68 from JuliaAstro/makie
Makie extension refactor
2 parents 585f94b + 159827c commit 625b0c0

File tree

7 files changed

+272
-221
lines changed

7 files changed

+272
-221
lines changed

CITATION.cff

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ authors:
1010
repository-code: https://github.com/JuliaAstro/SolarPosition.jl
1111
url: https://juliaastro.github.io/SolarPosition.jl/
1212
license: MIT
13-
version: 0.4.0
14-
date-released: 2026-01-05
13+
version: 0.4.1
14+
date-released: 2026-01-17
1515
abstract: >-
1616
SolarPosition.jl provides a simple, unified interface to a collection
1717
of validated solar position algorithms written in pure Julia.

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "SolarPosition"
22
uuid = "5b9d1343-a731-5a90-8730-7bf8d89bf3eb"
3-
version = "0.4.0"
3+
version = "0.4.1"
44
authors = ["Stefan de Lange"]
55

66
[workspace]

docs/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ makedocs(;
5151
"literature.md",
5252
"contributing.md",
5353
],
54+
draft = true,
5455
)
5556

5657
deploydocs(;

docs/src/guides/plotting.md

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
```@meta
2+
Draft = false
3+
```
4+
15
# [Plotting with Makie.jl](@id plotting-examples)
26

37
SolarPosition.jl provides a plotting extension for [Makie.jl](https://makie.juliaplots.org/stable/).
48

9+
The main plotting function is [`analemmas!`](@ref).
10+
511
To use it, simply import both the `SolarPosition` and `Makie` packages:
612

713
```@example plotting
@@ -11,72 +17,61 @@ using CairoMakie
1117
# supporting packages
1218
using Dates
1319
using TimeZones
14-
using DataFrames
1520
```
1621

1722
This example notebook is based on the [pvlib sun path example](https://pvlib-python.readthedocs.io/en/stable/gallery/solar-position/plot_sunpath_diagrams.html).
1823

1924
## Basic Sun Path Plotting
2025

21-
Let's start by defining an observer location and calculating solar positions for a whole year:
26+
The plotting functions generate analemmas (figure-8 patterns showing the sun's position at
27+
each hour of the day throughout the year). You simply provide an observer location and
28+
the year you want to visualize:
2229

2330
```@example plotting
2431
# Define observer location (New Delhi, India)
2532
# Parameters: latitude, longitude, altitude in meters
26-
tz = tz"Asia/Kolkata"
2733
obs = Observer(28.6, 77.2, 0.0)
28-
29-
# Generate hourly timestamps for a whole year
30-
times = collect(ZonedDateTime(DateTime(2019), tz):Hour(1):ZonedDateTime(DateTime(2020), tz))
31-
32-
# This returns a StructVector with solar position data
33-
positions = solar_position(obs, times)
34-
35-
# For plotting, we need to create a DataFrame that includes the timestamps
36-
df = DataFrame(positions)
37-
df.datetime = times
38-
39-
# We can inspect the first few entries
40-
first(df, 5)
34+
tz = TimeZone("Asia/Kolkata")
35+
year = 2019
4136
```
4237

4338
## Simple Sun Path Plot in Cartesian Coordinates
4439

45-
We can visualize solar positions in cartesian coordinates using the `sunpathplot`
46-
function:
40+
We can visualize solar positions in cartesian coordinates using the `analemmas!`
41+
function. The function automatically generates analemmas for all 24 hours of the day:
4742

4843
```@example plotting
4944
fig = Figure(backgroundcolor = (:white, 0.0), textcolor= "#f5ab35")
5045
ax = Axis(fig[1, 1], backgroundcolor = (:white, 0.0))
51-
sunpathplot!(ax, df, hour_labels = false)
46+
analemmas!(ax, obs, year, hour_labels = false)
5247
fig
5348
```
5449

5550
## Polar Coordinates with Hour Labels
5651

57-
We can also work directly with a `DataFrame`. Note that for plotting we need to include
58-
the datetime information, so we add it to the DataFrame.
59-
60-
Plotting in polar coordinates with `sunpathpolarplot` may yield a more intuitive
61-
representation of the solar path. Here, we also enable hourly labels for better
62-
readability:
52+
Plotting in polar coordinates with `analemmas!` may yield a more intuitive
53+
representation of the solar path. Here, we enable hourly labels for better readability:
6354

6455
```@example plotting
6556
fig2 = Figure(backgroundcolor = :transparent, textcolor= "#f5ab35", size = (800, 600))
6657
ax2 = PolarAxis(fig2[1, 1], backgroundcolor = "#1f2424")
67-
sunpathpolarplot!(ax2, df, hour_labels = true)
58+
analemmas!(ax2, obs, year, hour_labels = true)
59+
fig2
60+
```
6861

69-
# Draw individual days
62+
Now let's manually plot the full solar path for specific dates March 21, June 21, and
63+
December 21. Also known as the vernal equinox, summer solstice, and winter solstice,
64+
respectively:
65+
66+
```@example plotting
7067
line_objects = []
7168
for (date, label) in [(Date("2019-03-21"), "Mar 21"),
7269
(Date("2019-06-21"), "Jun 21"),
7370
(Date("2019-12-21"), "Dec 21")]
7471
times = collect(ZonedDateTime(DateTime(date), tz):Minute(5):ZonedDateTime(DateTime(date) + Day(1), tz))
7572
solpos = solar_position(obs, times)
7673
above_horizon = solpos.elevation .> 0
77-
day_df = DataFrame(solpos)
78-
day_df.datetime = times
79-
day_filtered = day_df[above_horizon, :]
74+
day_filtered = solpos[above_horizon]
8075
line_obj = lines!(ax2, deg2rad.(day_filtered.azimuth), day_filtered.zenith,
8176
linewidth = 2, label = label)
8277
push!(line_objects, line_obj)
@@ -101,11 +96,23 @@ It tells us when the sun rises, reaches its highest point, and sets. And hence a
10196
length of the day. From the figure we can also read that in June the days are longest,
10297
while in December they are shortest.
10398

104-
## Plotting without a custom axis
99+
## Custom Color Schemes
100+
101+
You can customize the color scheme used for the analemmas by passing a `colorscheme` argument.
102+
Here's an example using the `:balance` colorscheme.
105103

106-
Finally, we can also create plots without explicitly defining an axis beforehand.
107-
This is a more concise way to create plots, but it offers less customization:
104+
!!! info
105+
More colorschemes are available in the [Makie documentation](https://docs.makie.org/dev/explanations/colors).
108106

109107
```@example plotting
110-
sunpathpolarplot(df, hour_labels = true, colorbar = true)
108+
fig = Figure(backgroundcolor = (:white, 0.0), textcolor= "#f5ab35")
109+
ax = Axis(fig[1, 1], backgroundcolor = (:white, 0.0))
110+
analemmas!(ax, obs, year, hour_labels = false, colorscheme = :balance)
111+
fig
112+
```
113+
114+
## Docstrings
115+
116+
```@docs
117+
analemmas!
111118
```

examples/plotting.jl

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,27 @@
11
"""Plot solar positions using SolarPosition.jl with hourly labels."""
22

33
using Dates
4-
using TimeZones
5-
using DataFrames
64
using CairoMakie
75
using SolarPosition
86

97
# define observer location (latitude, longitude, altitude in meters)
10-
tz = tz"Asia/Kolkata"
11-
obs = Observer(28.6, 77.2, 0.0)
8+
obs = Observer(28.6, 77.2, 0.0) # New Delhi, India
9+
year = 2019
1210

13-
# a whole year of hourly timestamps
14-
times = collect(ZonedDateTime(DateTime(2019), tz):Hour(1):ZonedDateTime(DateTime(2020), tz))
15-
positions = solar_position(obs, times)
16-
17-
# plot positions from NamedTuple with hourly labels in polar coordinates
18-
df = DataFrame(positions)
19-
df.datetime = times
20-
sunpathplot(df)
21-
22-
# plot DataFrame with hourly labels in cartesian coordinates
23-
sunpathpolarplot(df, hour_labels = true, colorbar = true)
24-
25-
# plot DataFrame in polar coordinates with hourly labels
11+
# plot in cartesian coordinates with hourly labels
2612
fig = Figure()
27-
ax = PolarAxis(fig[1, 1], title = "Polar Coordinates with Hour Labels")
28-
sunpathpolarplot!(ax, df, hour_labels = true, colorbar = false)
13+
ax = Axis(fig[1, 1], title = "Cartesian Coordinates with Hour Labels")
14+
analemmas!(ax, obs, year, hour_labels = true)
2915
fig
3016

31-
# example without hourly labels for comparison
17+
# plot in polar coordinates with hourly labels
3218
fig2 = Figure()
33-
ax2 = Axis(fig2[1, 1], title = "Cartesian Coordinates (No Labels)")
34-
sunpathplot!(ax2, df; hour_labels = false, colorbar = true)
19+
ax2 = PolarAxis(fig2[1, 1], title = "Polar Coordinates with Hour Labels")
20+
analemmas!(ax2, obs, year, hour_labels = true)
3521
fig2
22+
23+
# example without hourly labels for comparison
24+
fig3 = Figure()
25+
ax3 = Axis(fig3[1, 1], title = "Cartesian Coordinates (No Labels)")
26+
analemmas!(ax3, obs, year, hour_labels = false)
27+
fig3

0 commit comments

Comments
 (0)