Skip to content

Commit 9c716d7

Browse files
add makie plots
1 parent cb275e3 commit 9c716d7

File tree

4 files changed

+288
-7
lines changed

4 files changed

+288
-7
lines changed

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[deps]
2+
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
23
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
34
GeoDatasets = "ddc7317b-88db-5cb5-a849-8449e5df04f9"
45
Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"

docs/make.jl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@ import Literate
1515
# )
1616

1717

18-
files = [
19-
joinpath(@__DIR__, "..", "examples", "01_build_roms.jl"),
20-
joinpath(@__DIR__, "..", "examples", "02_prep_roms.jl"),
21-
joinpath(@__DIR__, "..", "examples", "03_run_roms.jl"),
22-
joinpath(@__DIR__, "..", "examples", "04_plots.jl"),
23-
]
18+
files = joinpath.(@__DIR__, "..", "examples", [
19+
"01_build_roms.jl",
20+
"02_prep_roms.jl",
21+
"03_run_roms.jl",
22+
"04_plots.jl",
23+
"05_plots_makie.jl",
24+
])
2425

2526
all_notebooks = joinpath(mktempdir(),"all.jl")
2627
write(all_notebooks, join(read.(files,String),"\n"))
@@ -62,6 +63,7 @@ makedocs(
6263
"Preparation" => "02_prep_roms.md",
6364
"Running ROMS"=> "03_run_roms.md",
6465
"Plots" => "04_plots.md",
66+
"Plots (Makie)" => "05_plots_makie.md",
6567
"Additional information" => "additional_info.md",
6668
"Reference" => "reference.md",
6769
],

examples/04_plots.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ end
2222
# In this example, the bathymetry defined in the grid file is visualized. Make sure that your current working directory
2323
# contains the file `roms_grd_liguriansea.nc` (use e.g. `;cd ~/ROMS-implementation-test`)
2424

25-
using ROMS, PyPlot, NCDatasets, GeoDatasets, Statistics
25+
using ROMS, NCDatasets, GeoDatasets, Statistics
26+
using PyPlot
2627

2728
ds_grid = NCDataset("roms_grd_liguriansea.nc");
2829
lon = ds_grid["lon_rho"][:,:];

examples/05_plots_makie.jl

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
# # Plotting ROMS results and input files
2+
3+
#md # *The code here is also available as a notebook [04\_plots.ipynb](04_plots.ipynb).*
4+
#
5+
# The aim here is to visualize the model files with generic plotting and analsis packages rather than to use a model specific visualization tool which hides many details and might lack of flexibility.
6+
# The necessary files are already in the directory containing the model simulation and its
7+
# parent direction (`ROMS-implementation-test`). Downloading the files is only needed if you did not run the simulation.
8+
9+
using Pkg
10+
Pkg.activate("makie",shared=true)
11+
12+
grd_name = "roms_grd_liguriansea.nc"
13+
14+
if !isfile(grd_name)
15+
download("https://dox.ulg.ac.be/index.php/s/J9DXhUPXbyLADJa/download",grd_name)
16+
end
17+
18+
fname = "roms_his.nc"
19+
if !isfile(fname)
20+
download("https://dox.ulg.ac.be/index.php/s/17UWsY7tRNMDf4w/download",fname)
21+
end
22+
23+
# ## Bathymetry
24+
25+
# In this example, the bathymetry defined in the grid file is visualized. Make sure that your current working directory
26+
# contains the file `roms_grd_liguriansea.nc` (use e.g. `;cd ~/ROMS-implementation-test`)
27+
28+
using ROMS, NCDatasets, GeoDatasets, Statistics
29+
using CairoMakie # GeoMakie, GLMakie
30+
using CairoMakie: Point2f0
31+
32+
ds_grid = NCDataset("roms_grd_liguriansea.nc");
33+
lon = ds_grid["lon_rho"][:,:];
34+
lat = ds_grid["lat_rho"][:,:];
35+
h = ds_grid["h"][:,:]
36+
mask_rho = ds_grid["mask_rho"][:,:];
37+
38+
hmask = copy(h)
39+
hmask[mask_rho .== 0] .= missing;
40+
41+
fig = Figure();
42+
ga = Axis(fig[1, 1]; title = "smoothed bathymetry [m]",
43+
aspect = AxisAspect(1/cosd(mean(lat))));
44+
surf = surface!(ga,lon,lat,hmask, shading = NoShading, interpolate = false);
45+
Colorbar(fig[1,2],surf)
46+
xlims!(ga,extrema(lon))
47+
ylims!(ga,extrema(lat))
48+
save("smoothed_bathymetry.png",fig); nothing # hide
49+
50+
#md # ![](smoothed_bathymetry.png)
51+
52+
# ## Surface temperature
53+
54+
# The surface surface temperature (or salinity) of the model output or
55+
# climatology file can be visualized as follows.
56+
# The parameter `n` is the time instance to plot.
57+
# Make sure that your current working directory
58+
# contains the file to plot (use e.g. `;cd ~/ROMS-implementation-test/` to plot `roms_his.nc`)
59+
60+
61+
## instance to plot
62+
n = 1
63+
64+
ds = NCDataset("roms_his.nc")
65+
temp = ds["temp"][:,:,end,n]
66+
temp[mask_rho .== 0] .= missing;
67+
68+
if haskey(ds,"time")
69+
## for the climatology file
70+
time = ds["time"][:]
71+
else
72+
## for ROMS output
73+
time = ds["ocean_time"][:]
74+
end
75+
76+
fig = Figure()
77+
ga = Axis(fig[1, 1]; title = "sea surface temperature [degree C]")
78+
surf = surface!(ga,lon,lat,temp, shading = NoShading, interpolate = false);
79+
Colorbar(fig[1,2],surf);
80+
xlims!(ga,extrema(lon))
81+
ylims!(ga,extrema(lat))
82+
save("SST.png",fig); nothing # hide
83+
84+
#md # ![](SST.png)
85+
86+
# Exercise:
87+
# * Plot salinity
88+
# * Plot different time instance (`n`)
89+
# * Where do we specify that the surface values are to be plotted? Plot different layers.
90+
91+
92+
# ## Surface velocity and elevation
93+
94+
zeta = nomissing(ds["zeta"][:,:,n],NaN)
95+
u = nomissing(ds["u"][:,:,end,n],NaN);
96+
v = nomissing(ds["v"][:,:,end,n],NaN);
97+
98+
mask_u = ds_grid["mask_u"][:,:];
99+
mask_v = ds_grid["mask_v"][:,:];
100+
101+
u[mask_u .== 0] .= NaN;
102+
v[mask_v .== 0] .= NaN;
103+
zeta[mask_rho .== 0] .= NaN;
104+
105+
## ROMS uses an Arakawa C grid
106+
u_r = cat(u[1:1,:], (u[2:end,:] .+ u[1:end-1,:])/2, u[end:end,:], dims=1);
107+
v_r = cat(v[:,1:1], (v[:,2:end] .+ v[:,1:end-1])/2, v[:,end:end], dims=2);
108+
109+
## all sizes should be the same
110+
size(u_r), size(v_r), size(mask_rho)
111+
112+
fig = Figure();
113+
ga = Axis(fig[1, 1]; title = "surface currents [m/s] and elevation [m]",
114+
aspect = AxisAspect(1/cosd(mean(lat))));
115+
surf = surface!(ga,lon,lat,zeta, shading = NoShading, interpolate = false);
116+
Colorbar(fig[1,2],surf);
117+
## plot only a single arrow for r x r grid cells
118+
r = 3;
119+
i = 1:r:size(lon,1);
120+
j = 1:r:size(lon,2);
121+
s = 0.6;
122+
arrows!(ga,lon[i,j][:],lat[i,j][:],s*u_r[i,j][:],s*v_r[i,j][:]);
123+
i=j=5;
124+
arrows!(ga,[11],[44],[s*1],[0]);
125+
text!(ga,[11],[44],text="1 m/s")
126+
xlims!(ga,extrema(lon))
127+
ylims!(ga,extrema(lat))
128+
save("surface_zeta_uv.png",fig); nothing # hide
129+
130+
#md # ![](surface_zeta_uv.png)
131+
132+
# Exercise:
133+
# * The surface currents seems to follow lines of constant surface elevation. Explain why this is to be expected.
134+
135+
# ## Vertical section
136+
137+
# In this example we will plot a vertical section by slicing the
138+
# model output at a given index.
139+
140+
# It is very important that the parameters (`opt`) defining the vertical layer match the parameters values choosen when ROMS was setup.
141+
142+
opt = (
143+
Tcline = 50, # m
144+
theta_s = 5, # surface refinement
145+
theta_b = 0.4, # bottom refinement
146+
nlevels = 32, # number of vertical levels
147+
Vtransform = 2,
148+
Vstretching = 4,
149+
)
150+
151+
hmin = minimum(h)
152+
hc = min(hmin,opt.Tcline)
153+
z_r = ROMS.set_depth(opt.Vtransform, opt.Vstretching,
154+
opt.theta_s, opt.theta_b, hc, opt.nlevels,
155+
1, h);
156+
157+
temp = nomissing(ds["temp"][:,:,:,n],NaN);
158+
159+
mask3 = repeat(mask_rho,inner=(1,1,opt.nlevels))
160+
lon3 = repeat(lon,inner=(1,1,opt.nlevels))
161+
lat3 = repeat(lat,inner=(1,1,opt.nlevels))
162+
163+
temp[mask3 .== 0] .= NaN;
164+
165+
i = 20;
166+
167+
fig = Figure();
168+
ga = Axis(fig[1, 1]; title = "temperature at $(round(lon[i,1],sigdigits=4)) °E",
169+
xlabel = "latitude",
170+
ylabel = "depth [m]",
171+
backgroundcolor=:white,
172+
);
173+
surf = surface!(ga,lat3[i,:,:],z_r[i,:,:],temp[i,:,:],shading = NoShading, interpolate = false);
174+
xlims!(ga,extrema(lat3[i,:,:]))
175+
ylims!(ga,-300,0);
176+
Colorbar(fig[1,2],surf);
177+
ax2 = Axis(
178+
fig[1, 1],
179+
width = Relative(0.4),
180+
height = Relative(0.3),
181+
halign = 0.13,
182+
valign = 0.18,
183+
aspect = AxisAspect(1/cosd(mean(lat))),
184+
backgroundcolor=:white);
185+
## inset plot
186+
poly!(ax2,Point2f0[(lon[1,1], lat[1,1]), (lon[1,1], lat[1,end]), (lon[end,1], lat[1,end]), (lon[end,1], lat[1,1])], color = [:white, :white, :white, :white])
187+
surf = surface!(ax2,lon[:,1],lat[1,:],temp[:,:,end], shading = NoShading, interpolate = false);
188+
#ax2.pcolormesh(lon,lat,temp[:,:,end])
189+
#ax2.set_aspect(1/cosd(mean(lat)))
190+
lines!(ax2,lon[i,[1,end]],lat[i,[1,end]],color="magenta")
191+
xlims!(ax2,extrema(lon))
192+
ylims!(ax2,extrema(lat))
193+
194+
save("temp_section1.png",fig);
195+
196+
#md # ![temp_section1](temp_section1.png)
197+
198+
# Exercise:
199+
# * Plot a section at different longitude and latitude
200+
201+
# ## Horizontal section
202+
203+
# A horizontal at the fixed depth of 200 m is extracted and plotted.
204+
205+
tempi = ROMS.model_interp3(lon,lat,z_r,temp,lon,lat,[-200])
206+
mlon,mlat,mdata = GeoDatasets.landseamask(resolution='f', grid=1.25)
207+
208+
ii = findall(minimum(lon) .<= mlon .<= maximum(lon))
209+
jj = findall(minimum(lat) .<= mlat .<= maximum(lat))
210+
211+
mlon = mlon[ii]
212+
mlat = mlat[jj]
213+
mdata = mdata[ii,jj]
214+
215+
fig = Figure();
216+
ga = Axis(fig[1, 1]; title = "temperature at 200 m [°C]",
217+
xlabel = "longitude",
218+
ylabel = "latitude",
219+
);
220+
surf = surface!(ga,lon,lat,tempi[:,:,1],shading = NoShading, interpolate = false);
221+
Colorbar(fig[1,2],surf);
222+
contourf!(ga,mlon,mlat,mdata,levels=[0.5, 3],colormap=[:grey])
223+
xlims!(ga,extrema(lon))
224+
ylims!(ga,extrema(lat))
225+
fig
226+
227+
save("temp_hsection_200.png",fig);
228+
229+
#md # ![](temp_hsection_200.png)
230+
231+
# ## Arbitrary vertical section
232+
233+
# The vectors `section_lon` and `section_lat` define the coordinates where we want to extract
234+
# the surface temperature.
235+
236+
237+
section_lon = LinRange(8.18, 8.7,100);
238+
section_lat = LinRange(43.95, 43.53,100);
239+
240+
using Interpolations
241+
242+
function section_interp(v)
243+
itp = interpolate((lon[:,1],lat[1,:]),v,Gridded(Linear()))
244+
return itp.(section_lon,section_lat)
245+
end
246+
247+
section_temp = mapslices(section_interp,temp,dims=(1,2))
248+
section_z = mapslices(section_interp,z_r,dims=(1,2))
249+
section_x = repeat(section_lon,inner=(1,size(temp,3)))
250+
251+
252+
fig = Figure();
253+
ga = Axis(fig[1, 1]; title = "temperature section [°C]",
254+
xlabel = "longitude",
255+
ylabel = "depth",
256+
);
257+
surf = surface!(ga,section_x,section_z[:,1,:],section_temp[:,1,:],shading = NoShading, interpolate = false)
258+
ylims!(ga,-500,0)
259+
Colorbar(fig[1,2],surf);
260+
## inset plot
261+
ax2 = Axis(
262+
fig[1, 1],
263+
width = Relative(0.4),
264+
height = Relative(0.3),
265+
halign = 0.6,
266+
valign = 0.18,
267+
aspect = AxisAspect(1/cosd(mean(lat))),
268+
backgroundcolor=:white);
269+
poly!(ax2,Point2f0[(lon[1,1], lat[1,1]), (lon[1,1], lat[1,end]), (lon[end,1], lat[1,end]), (lon[end,1], lat[1,1])], color = [:white, :white, :white, :white])
270+
surf = surface!(ax2,lon[:,1],lat[1,:],temp[:,:,end], shading = NoShading, interpolate = false);
271+
xlims!(ax2,extrema(lon))
272+
ylims!(ax2,extrema(lat))
273+
fig
274+
275+
save("temp_vsection.png",fig);
276+
277+
#md # ![](temp_vsection.png)

0 commit comments

Comments
 (0)