|
1 | 1 | """
|
2 |
| -Calculating and plotting the divergence of sea current vectors |
3 |
| -============================================================== |
| 2 | +Calculating and plotting the divergence of sea currents |
| 3 | +======================================================= |
4 | 4 |
|
5 | 5 | In this recipe, we will calculate the divergence of depth-averaged
|
6 | 6 | currents in the Irish Sea, then plot the divergence as a contour
|
7 |
| -fill plot underneath the vectors themselves in a vector plot. |
| 7 | +fill plot underneath the vectors themselves in the form of a vector plot. |
8 | 8 | """
|
9 | 9 |
|
| 10 | +# %% |
| 11 | +# 1. Import cf-python and cf-plot: |
10 | 12 | import cfplot as cfp
|
11 | 13 | import cf
|
12 | 14 |
|
13 |
| -f = cf.read("~/recipes_break/new/POLCOMS_WAM_ZUV_01_16012006.nc") |
14 |
| -print(f) |
| 15 | +# %% |
| 16 | +# 2. Read the fields in: |
| 17 | +f = cf.read( |
| 18 | + "~/summerstudents/final-recipes/new-required-datasets/POLCOMS_WAM_ZUV_01_16012006.nc") |
15 | 19 |
|
16 |
| -# Get separate vector components |
| 20 | +# %% |
| 21 | +# 3. Get the separate vector components, which are stored as separate fields. |
| 22 | +# The first, 'u', corresponds to the eastward component and the second, 'v', |
| 23 | +# the northward component: |
17 | 24 | u = f[0]
|
18 | 25 | v = f[1]
|
19 |
| -print(u) |
20 |
| -print(v) |
21 | 26 |
|
22 |
| -# First get rid of the ocean sigma coord size 1 axis |
| 27 | +# %% |
| 28 | +# 4. Squeeze the fields to remove the size 1 axes in each case: |
23 | 29 | u = u.squeeze()
|
24 | 30 | v = v.squeeze()
|
25 | 31 |
|
26 |
| -# Now we need to use some means to condense the u and v fields in the same way into |
27 |
| -# having 1 time point, not 720 - for example we can just pick a time value out: |
28 |
| -print("Times are", v.construct("T").data.datetime_as_string) |
29 |
| -chosen_time = "2006-01-15 23:30:00" # 720 choices to choose from! |
30 |
| -v_1 = v.subspace(T=cf.dt(chosen_time)) |
| 32 | +# %% |
| 33 | +# 5. Consider the currents at a set point in time. To do this we |
| 34 | +# select one of the 720 datetime sample points in the fields to |
| 35 | +# investigate, in this case by subspacing to pick out a particular |
| 36 | +# datetime value we saw within the time coordinate data of the field (but |
| 37 | +# you could also use indexing or filtering to select a specific value). |
| 38 | +# Once we subspace to one datetime, we squeeze out the size 1 time axis |
| 39 | +# in each case: |
| 40 | +chosen_time = "2006-01-15 23:30:00" # 720 choices to pick from, try this one! |
31 | 41 | u_1 = u.subspace(T=cf.dt(chosen_time))
|
32 |
| -v_1 = v_1.squeeze() |
| 42 | +v_1 = v.subspace(T=cf.dt(chosen_time)) |
33 | 43 | u_1 = u_1.squeeze()
|
34 |
| -print(u_1) |
35 |
| -print(v_1) |
36 |
| - |
37 |
| -# Are now in a plottable form! Let's give it a go: |
38 |
| -### cfp.vect(u=u_1, v=v_1) |
39 |
| -# Need to play around with the relative length and spacing of the vectors, using these paramters: |
40 |
| -###cfp.vect(u=u_1, v=v_1, key_length=10, scale=50, stride=2) |
41 |
| - |
42 |
| -# Note that there appear to be some really large vectors all pointing in the |
43 |
| -# same direction which are spamming the plot. We need to remove these. By |
44 |
| -# looking at the data we can see what these are and work out how to remove them: |
45 |
| - |
46 |
| -# ... shows more of the array |
47 |
| - |
48 |
| -# Can see there are lots of -9999 values, seemingly used as a fill/placeholder value |
49 |
| -# so we need to remove those so we can plot the menaingful vectors |
50 |
| -# Apply steps to mask the -9999 fill values, which spam the plot, to x_1 |
51 |
| -u_2 = u_1.where(cf.lt(-9e+03), cf.masked) |
52 |
| -v_2 = v_1.where(cf.lt(-9e+03), cf.masked) |
53 |
| -print(u_2) |
54 |
| -print(v_2) |
55 |
| - |
56 |
| -# We can even plot the final field, effective wave height, as the |
57 |
| -# background contour! |
58 |
| -w = f[2] |
59 |
| -w_1 = w.subspace(T=cf.dt(chosen_time)) |
60 |
| -# This field also needs masking for those data points. |
61 |
| -w_2 = w_1.where(cf.lt(-9e+03), cf.masked) |
62 |
| -print(w_2) |
| 44 | +v_1 = v_1.squeeze() |
63 | 45 |
|
| 46 | +# %% |
| 47 | +# 6. |
| 48 | +# When inspecting the u and v fields using cf inspection methods such as |
| 49 | +# from print(u_1.data) and u_1.data.dump(), for example, we can see that there are |
| 50 | +# lots of -9999 values in their data array, apparently used as a |
| 51 | +# fill/placeholder value, including to indicate undefined data over the land. |
| 52 | +# In order for these to not skew the data and dominate the plot, we need |
| 53 | +# to mask values matching this, so that only meaningful values remain. |
| 54 | +u_2 = u_1.where(cf.lt(-9000), cf.masked) |
| 55 | +v_2 = v_1.where(cf.lt(-9000), cf.masked) |
64 | 56 |
|
65 |
| -# Plot divergence in the background |
| 57 | +# %% |
| 58 | +# 7. Calculate the divergence using the 'div_xy' function operating on the |
| 59 | +# vector eastward and northward components as the first and second argument |
| 60 | +# respectively. We need to calculate this for the latitude-longitude plane |
| 61 | +# of the Earth, defined in spherical polar coordinates, so we must specify |
| 62 | +# the Earth's radius for the appropriate calculation: |
66 | 63 | div = cf.div_xy(u_2, v_2, radius="earth")
|
67 | 64 |
|
68 |
| - |
69 |
| -# Our final basic plot: |
70 |
| -cfp.mapset(resolution="10m") # makes UK coastline more high-res |
71 |
| -cfp.gopen(file=f"irish-sea-currents-with-divergence-{chosen_time}.png") |
| 65 | +# %% |
| 66 | +# 8. Generate the final plot. First we configure the overall plot by |
| 67 | +# making the map higher resolution, to show the coastlines of the UK and |
| 68 | +# Ireland in greater detail, and changing the colourmap to better reflect |
| 69 | +# the data which can be positive or negative, i.e. has 0 as the 'middle' |
| 70 | +# value of significance, so should use a diverging colour map. Then we |
| 71 | +# plot the current vectors, noting we had to play around with the 'stride' |
| 72 | +# and 'scale' parameter values to adjust the vector spacing and size so that |
| 73 | +# the vector field is best represented and visible without over-cluttering |
| 74 | +# the plot. Finally we plot the divergence as a contour plot without any |
| 75 | +# lines showing. This compound plot is saved on one canvas using 'gopen' |
| 76 | +# and 'gclose' to wrap the two plotting calls: |
| 77 | +cfp.mapset(resolution="10m") |
72 | 78 | cfp.cscale("ncl_default")
|
| 79 | +cfp.gopen( |
| 80 | + file=f"irish-sea-currents-divergence-{chosen_time.replace(' ', '-')}.png") |
73 | 81 | cfp.vect(u=u_2, v=v_2, stride=6, scale=3, key_length=1)
|
74 | 82 | cfp.con(
|
75 | 83 | div,
|
76 | 84 | lines=False,
|
77 | 85 | title=(
|
78 |
| - f"Depth-averaged Irish Sea currents at {chosen_time} " |
79 |
| - "with their divergence shown" |
| 86 | + f"Depth-averaged Irish Sea currents at {chosen_time} with " |
| 87 | + "their divergence" |
80 | 88 | )
|
81 | 89 | )
|
82 | 90 | cfp.gclose()
|
0 commit comments