Skip to content

Commit 1bb5acf

Browse files
committed
General re-organisation : Much updated + some moved between notebooks.
1 parent 2513e84 commit 1bb5acf

File tree

6 files changed

+1312
-812
lines changed

6 files changed

+1312
-812
lines changed

notebooks/.notebook_shadow_copies/Sec_01_Load_and_Examine.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ First run some preliminary Python setup, imports etc ...
1919
```python
2020
# import the top-level Iris package
2121
import iris
22-
# mask some irritating warnings about new loading behaviour in Iris 3.4
23-
iris.FUTURE.datum_support = True
2422

25-
# import some local routines to ask the test data
23+
# import local routines handling access to some test data
2624
from testdata_fetching import lfric_filepth
2725
```
2826

@@ -52,6 +50,8 @@ from iris.experimental.ugrid.load import PARSE_UGRID_ON_LOAD
5250
```
5351

5452
<!-- #region -->
53+
---
54+
5555
The variable `lfric_filepath` is already set up, pointing to a suitable test file.
5656

5757
**Exercise : Load all data from `lfric_filepath`, with the UGRID loading enabled, and print the first 10 cubes.**

notebooks/.notebook_shadow_copies/Sec_02_Meshes.md

Lines changed: 50 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -70,33 +70,41 @@ Here is an example of what that looks like :--
7070

7171
This does not happen in current LFRic data : the mesh is a "cubesphere" (see later images), and all cells have four corners.
7272

73-
```python
74-
# Get sample files, as used in Section#01
7573

76-
from pathlib import Path
77-
datadir = Path('/scratch/sworsley/lfric_data')
74+
---
75+
76+
## Fetch some sample unstructured data, as used in Section#01
7877

79-
import iris
80-
from iris.experimental.ugrid.load import PARSE_UGRID_ON_LOAD
81-
iris.FUTURE.datum_support = True # avoids some irritating warnings
78+
**Import the data-access routine `lfric_rh_singletime_2d` from `testdata_fetching`, and call it to get a single two-dimensional test cube.**
8279

83-
um_filepth = datadir / '20210324T0000Z_um_latlon.nc'
84-
lfric_filepth = datadir / '20210324T0000Z_lf_ugrid.nc'
80+
```python
81+
## TODO : remove later -- this bit is temporary, for initial testing with C48 data
82+
from testdata_fetching import switch_data
83+
switch_data(use_newer_smaller_c48_data=True)
8584
```
8685

8786
```python
88-
with PARSE_UGRID_ON_LOAD.context():
89-
lfric_rh = iris.load_cube(lfric_filepth, 'relative_humidity_at_screen_level')
90-
# Rename this cube, to make it clear wich model this came from.
91-
lfric_rh.rename('LFRic Rh data')
87+
from testdata_fetching import lfric_rh_singletime_2d
88+
lfric_rh = lfric_rh_singletime_2d()
9289
```
9390

91+
**Print the cube, and its `cube.mesh`**
92+
9493
```python
9594
print(lfric_rh)
9695
print('\n----\n')
9796
print(lfric_rh.mesh)
9897
```
9998

99+
```python
100+
# TODO: work this up for user input
101+
102+
# Simply plot that ..
103+
from pv_conversions import pv_from_lfric_cube
104+
pv = pv_from_lfric_cube(lfric_rh)
105+
pv.plot() #jupyter_backend='static')
106+
```
107+
100108
```python
101109

102110
```
@@ -120,7 +128,9 @@ rh_t0 = lfric_rh[0]
120128
<!-- #endregion -->
121129

122130
```python
123-
rh_t0 = lfric_rh[0]
131+
from testdata_fetching import lfric_rh_singletime_2d
132+
133+
rh_t0 = lfric_rh_singletime_2d()
124134
```
125135

126136
<!-- #region jp-MarkdownHeadingCollapsed=true tags=[] -->
@@ -180,7 +190,29 @@ pv
180190
( Note: like `Cube`s + `CubeList`s, these `PolyData` objects are provided with a specific visible within the Jupyter notebooks. This is displayed when you just enter the variable in a cell.
181191
You can also use "print(x)" to display the standard string representation of the object, but usually the notebook-style output is a bit more useful. )
182192

183-
<!-- #region -->
193+
194+
---
195+
### Quick 3d plotting
196+
197+
For a really quick, basic plot, you can display a PolyData as a VTK view with PyVista, by simply calling its `.plot` method.
198+
199+
**Call the `plot` routine of the PolyData object. An output should appear.**
200+
201+
```python
202+
pv.plot()
203+
```
204+
205+
**NOTES**:
206+
* this plot is interactive -- try dragging to rotate, and the mouse scroll-wheel to zoom
207+
* this obviously causes some clutter and uses up some space (e.g. you can't easily scroll past it)
208+
* To ***remove*** a plot output, use "Clear Output" from the "Edit" menu (or from right-click on the cell)
209+
* alternatively, set the keyword `jupyter_backend='static'` in the command, for output as a plain image
210+
211+
There are a lot more keywords available to [the `PolyData.plot()` method](https://docs.pyvista.org/api/core/_autosummary/pyvista.PolyData.plot.html), but it is not ideal to overcomplicate these calls. :
212+
Finer control is better achieved in a different ways : See more detail on plotting in [the Plotting section](./Sec_03_Plotting.ipynb).
213+
214+
215+
<!-- #region tags=[] -->
184216
### Create a plotter, and display 3D visualisation
185217

186218
Finally, we will plot the 'PolyData' object via PyVista.
@@ -229,145 +261,19 @@ plotter.show()
229261
</details>
230262
<!-- #endregion -->
231263

232-
**NOTES**:
233-
* this operation currently generates a warning message, which however can be ignored
234-
* when translated to a simple Python file + run, these plots (or at least the folowing one) can cause SegmentationFault
235-
* ***TODO: this needs investigating, fix for confidence + useability***
236-
* it is interactive, so it causes some clutter and uses up some space.
237-
To remove plot outputs, use "Clear Output" from the "Edit" menu (or from right-click on the cell)
238-
239264
```python
240265
plotter.show()
241266
```
242267

243268
**Some odd notes:**
244269
* By default, `plotter.show()` opens an interactive window : **you can rotate and zoom it with the mouse**.
245-
* you can instead generate static output (try `interactive=False`)
270+
* you can instead generate static output
271+
* in a notebook, you do this with `jupyter_backend='static'`
272+
* or in a Python session, try `interactive=False`
246273
* VTK/PyVista doesn't use plot "types".
247274
Instead, you add meshes to a plotter + can subsequently control the presentation.
248275
* GeoVista can also produce more familiar 2D plots (see on ...)
249276

250277

251278

252279
***TODO:*** can suggest some of these as follow-on exercises
253-
254-
255-
# Comparing UM and LFRic fields
256-
257-
```python
258-
um_rh = iris.load_cube(um_filepth, 'relative_humidity')
259-
# Rename so we are clear which model this came from
260-
lfric_rh.rename('UM Rh data')
261-
um_rh
262-
```
263-
264-
```python
265-
from pv_conversions import pv_from_um_cube
266-
um_pv = pv_from_um_cube(um_rh[0])
267-
```
268-
269-
## Simple side-by-side plotting : UM vs LFRic data
270-
271-
```python
272-
my_plotter = GeoPlotter(shape=(1, 2))
273-
274-
my_plotter.subplot(0, 0)
275-
my_plotter.add_coastlines()
276-
my_plotter.add_mesh(um_pv, show_edges=True, cmap='magma')
277-
278-
my_plotter.subplot(0, 1)
279-
my_plotter.add_coastlines()
280-
my_plotter.add_mesh(pv, show_edges=True, cmap='magma')
281-
282-
my_plotter.link_views()
283-
# Use a preset "Nice" viewpoint showing off the data
284-
viewpoint = [
285-
(-0.709497461391866, -1.2057617579427944, 1.4232488035268644),
286-
(0.0, 0.0, 0.0),
287-
(-0.48482598598375826, 0.7715244238081727, 0.41193910567260306)
288-
]
289-
my_plotter.camera_position = viewpoint
290-
291-
```
292-
293-
```python
294-
my_plotter.show()
295-
```
296-
297-
## A handy hint : how to record + re-use a camera view
298-
299-
```python
300-
viewpoint = my_plotter.camera_position
301-
viewpoint
302-
```
303-
304-
```python
305-
# This pre-loaded position focusses on a cubesphere "corner" in the middle East
306-
viewpoint = [
307-
(0.9550352379408845, 0.9378277371075855, 0.9637172962958191),
308-
(0.0, 0.0, 0.0),
309-
(-0.3202752464164225, -0.5004192729867466, 0.8043657860428399)
310-
]
311-
```
312-
313-
```python
314-
# Plot just the LFRIC data with the same view ...
315-
new_plotter = GeoPlotter()
316-
new_plotter.add_coastlines()
317-
new_plotter.add_mesh(pv, show_edges=True)
318-
new_plotter.camera_position = viewpoint
319-
new_plotter.show()
320-
```
321-
322-
```python
323-
324-
```
325-
326-
```python
327-
# WIP : projected 2D plotting
328-
```
329-
330-
```python
331-
# GeoVista coastline projection not yet supported. Use a representation of coastlines as Cube data instead.
332-
333-
# import requests
334-
# r = requests.get("https://github.com/SciTools-incubator/presentations/raw/main/ngms_champions_2022-04-12/coastline_grid.nc")
335-
# open("coastline_grid.nc", "wb").write(r.content)
336-
337-
# coastline_cube = iris.load_cube("coastline_grid.nc")
338-
339-
# coastline_polydata = pv_from_structcube(coastline_cube)
340-
# # Remove all NaN's (grid squares that aren't on a coast).
341-
# coastline_polydata = coastline_polydata.threshold()
342-
```
343-
344-
```python
345-
def plot_projected(my_polydata, plotter=None):
346-
"""Plot polydata on a given plotter"""
347-
if plotter is None:
348-
plotter = GeoPlotter()
349-
# Add the coastline cells 'above' the data itself.
350-
plotter.add_mesh(
351-
coastline_polydata,
352-
color="white",
353-
show_edges=True,
354-
edge_color="white",
355-
radius=1.1, # For globe plots
356-
zlevel=10, # For planar plots
357-
)
358-
plot_polydata = my_polydata.copy()
359-
plotter.add_mesh(plot_polydata)
360-
# if plotter.crs != WGS84:
361-
# # Projected plot.
362-
# plotter.camera_position = "xy"
363-
# backend = "static"
364-
# else:
365-
# backend = "pythreejs"
366-
# backend = "static"
367-
plotter.show() # jupyter_backend=backend)
368-
```
369-
370-
```python
371-
# Plot these side-by-side ...
372-
373-
```

0 commit comments

Comments
 (0)