Skip to content

Commit 04b60f9

Browse files
committed
Add contours to plots
1 parent 7a8cd96 commit 04b60f9

File tree

1 file changed

+83
-30
lines changed
  • compass/ocean/tests/isomip_plus/viz

1 file changed

+83
-30
lines changed

compass/ocean/tests/isomip_plus/viz/plot.py

Lines changed: 83 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import progressbar
1010
import xarray
1111
from matplotlib.collections import PatchCollection
12-
from matplotlib.colors import LogNorm
12+
from matplotlib.colors import LogNorm, SymLogNorm
1313
from matplotlib.patches import Polygon
1414

1515

@@ -77,7 +77,7 @@ def __init__(self, inFolder='.', outFolder='plots', expt='Ocean0',
7777

7878
plt.switch_backend('Agg')
7979

80-
def plot_melt_time_series(self, sshMax=None):
80+
def plot_melt_time_series(self, sshMax=None, wctMax=None):
8181
"""
8282
Plot a series of image for each of several variables related to melt
8383
at the ice shelf-ocean interface: mean melt rate, total melt flux,
@@ -89,21 +89,28 @@ def plot_melt_time_series(self, sshMax=None):
8989
rho_fw = 1000.
9090
secPerYear = 365 * 24 * 60 * 60
9191

92+
suffix = ''
9293
areaCell = self.dsMesh.areaCell
9394
iceMask = self.ds.timeMonthly_avg_landIceFraction
9495
meltFlux = self.ds.timeMonthly_avg_landIceFreshwaterFlux
9596
if sshMax is not None:
9697
ssh = self.ds.timeMonthly_avg_ssh
9798
iceMask = iceMask.where(ssh < sshMax)
99+
suffix = f'_sshMax{sshMax}'
100+
elif wctMax is not None:
101+
H = self.ds.timeMonthly_avg_layerThickness.sum(dim='nVertLevels')
102+
iceMask = iceMask.where(H < wctMax)
103+
suffix = f'_wctMax{wctMax}'
98104

99105
totalMeltFlux = (meltFlux * areaCell * iceMask).sum(dim='nCells')
100106
totalArea = (areaCell * iceMask).sum(dim='nCells')
101107
meanMeltRate = totalMeltFlux / totalArea / rho_fw * secPerYear
102108
self.plot_time_series(meanMeltRate, 'mean melt rate', 'meanMeltRate',
103109
'm/yr')
110+
print(meanMeltRate.values)
104111

105112
self.plot_time_series(1e-6 * totalMeltFlux, 'total melt flux',
106-
'totalMeltFlux', 'kT/yr')
113+
f'totalMeltFlux{suffix}', 'kT/yr')
107114

108115
prefix = 'timeMonthly_avg_landIceBoundaryLayerTracers_'
109116
boundary_layer_temperature = \
@@ -115,13 +122,13 @@ def plot_melt_time_series(self, sshMax=None):
115122
da = (da * areaCell * iceMask).sum(dim='nCells') / totalArea
116123

117124
self.plot_time_series(da, 'mean thermal driving',
118-
'meanThermalDriving', 'deg C')
125+
f'meanThermalDriving{suffix}', 'deg C')
119126

120127
da = self.ds.timeMonthly_avg_landIceFrictionVelocity
121128
da = (da * areaCell * iceMask).sum(dim='nCells') / totalArea
122129

123130
self.plot_time_series(da, 'mean friction velocity',
124-
'meanFrictionVelocity', 'm/s')
131+
f'meanFrictionVelocity{suffix}', 'm/s')
125132

126133
def plot_time_series(self, da, nameInTitle, prefix, units=None,
127134
figsize=(12, 6), color=None, overwrite=True):
@@ -344,7 +351,7 @@ def plot_overturning_streamfunction(self, vmin=-0.3, vmax=0.3):
344351
if self.showProgress:
345352
bar.finish()
346353

347-
def plot_melt_rates(self, vmin=-100., vmax=100.):
354+
def plot_melt_rates(self, vmin=0., vmax=50.):
348355
"""
349356
Plot a series of image of the melt rate
350357
@@ -363,7 +370,7 @@ def plot_melt_rates(self, vmin=-100., vmax=100.):
363370

364371
self.plot_horiz_series(da, 'melt rate', prefix='meltRate',
365372
oceanDomain=False, units='m/yr', vmin=vmin,
366-
vmax=vmax, cmap='cmo.curl')
373+
vmax=vmax, cmap='cmo.amp')
367374

368375
def plot_ice_shelf_boundary_variables(self):
369376
"""
@@ -401,7 +408,7 @@ def plot_ice_shelf_boundary_variables(self):
401408
self.plot_horiz_series(da, 'thermal driving',
402409
prefix='thermalDriving',
403410
oceanDomain=False, units='deg C',
404-
vmin=-2, vmax=2, cmap='cmo.thermal')
411+
vmin=-2, vmax=2, cmap='cmo.curl')
405412

406413
da = boundary_layer_salinity - interface_salinity
407414
self.plot_horiz_series(da, 'haline driving',
@@ -412,8 +419,9 @@ def plot_ice_shelf_boundary_variables(self):
412419
self.plot_horiz_series(self.ds.timeMonthly_avg_landIceFrictionVelocity,
413420
'friction velocity',
414421
prefix='frictionVelocity',
415-
oceanDomain=True, units='m/s',
416-
vmin=0, vmax=0.05, cmap='cmo.speed')
422+
oceanDomain=False, units='m/s',
423+
vmin=1.e-4, vmax=1.e-1, cmap='cmo.speed',
424+
cmap_scale='log')
417425

418426
def plot_temperature(self):
419427
"""
@@ -438,8 +446,8 @@ def plot_salinity(self):
438446
self.plot_3d_field_top_bot_section(da,
439447
nameInTitle='salinity',
440448
prefix='Salinity', units='PSU',
441-
vmin=33.8, vmax=34.7,
442-
cmap='cmo.haline')
449+
vmin=1., vmax=34.6,
450+
cmap='cmo.haline', cmap_scale='log')
443451

444452
def plot_potential_density(self):
445453
"""
@@ -478,7 +486,7 @@ def plot_horiz_series(self, da, nameInTitle, prefix, oceanDomain,
478486
units=None, vmin=None, vmax=None, cmap=None,
479487
cmap_set_under=None, cmap_set_over=None,
480488
cmap_scale='linear', time_indices=None,
481-
figsize=(9, 3)):
489+
figsize=(9, 3), contour_field=None):
482490
"""
483491
Plot a series of image of a given variable
484492
@@ -533,6 +541,8 @@ def plot_horiz_series(self, da, nameInTitle, prefix, oceanDomain,
533541
for tIndex in time_indices:
534542
self.update_date(tIndex)
535543
field = da.isel(Time=tIndex).values
544+
if contour_field is not None:
545+
contour_field = contour_field.isel(Time=tIndex).values
536546
outFileName = '{}/{}/{}_{:04d}.png'.format(
537547
self.outFolder, prefix, prefix, tIndex + 1)
538548
if units is None:
@@ -544,15 +554,17 @@ def plot_horiz_series(self, da, nameInTitle, prefix, oceanDomain,
544554
vmax=vmax, cmap=cmap,
545555
cmap_set_under=cmap_set_under,
546556
cmap_set_over=cmap_set_over,
547-
cmap_scale=cmap_scale, figsize=figsize)
557+
cmap_scale=cmap_scale, figsize=figsize,
558+
contour_field=contour_field)
548559
if self.showProgress:
549560
bar.update(tIndex + 1)
550561
if self.showProgress:
551562
bar.finish()
552563

553564
def plot_3d_field_top_bot_section(self, da, nameInTitle, prefix,
554565
units=None, vmin=None, vmax=None,
555-
cmap=None, cmap_set_under=None,
566+
cmap=None, cmap_scale='linear',
567+
cmap_set_under=None,
556568
cmap_set_over=None):
557569
"""
558570
Plot a series of images of a given 3D variable showing the value
@@ -608,6 +620,7 @@ def plot_3d_field_top_bot_section(self, da, nameInTitle, prefix,
608620
'top {}'.format(nameInTitle),
609621
'top{}'.format(prefix), oceanDomain=True,
610622
vmin=vmin, vmax=vmax, cmap=cmap,
623+
cmap_scale=cmap_scale,
611624
cmap_set_under=cmap_set_under,
612625
cmap_set_over=cmap_set_over)
613626

@@ -630,7 +643,8 @@ def plot_3d_field_top_bot_section(self, da, nameInTitle, prefix,
630643
self.plot_horiz_series(daBot,
631644
'bot {}'.format(nameInTitle),
632645
'bot{}'.format(prefix), oceanDomain=True,
633-
vmin=vmin, vmax=vmax, cmap=cmap)
646+
vmin=vmin, vmax=vmax, cmap_scale=cmap_scale,
647+
cmap=cmap)
634648

635649
daSection = da.isel(nCells=self.sectionCellIndices)
636650

@@ -659,7 +673,8 @@ def plot_3d_field_top_bot_section(self, da, nameInTitle, prefix,
659673
self._plot_vert_field(self.X, self.Z[tIndex, :, :],
660674
field, title=title,
661675
outFileName=outFileName,
662-
vmin=vmin, vmax=vmax, cmap=cmap)
676+
vmin=vmin, vmax=vmax, cmap=cmap,
677+
show_boundaries=False, cmap_scale=cmap_scale)
663678
if self.showProgress:
664679
bar.update(tIndex + 1)
665680
if self.showProgress:
@@ -718,6 +733,7 @@ def plot_layer_interfaces(self, figsize=(9, 5)):
718733
plt.plot(1e-3 * X[z_index, :], Z[z_index, :], 'k')
719734
plt.plot(1e-3 * X[0, :], Z[0, :], 'b')
720735
plt.plot(1e-3 * X[0, :], self.zBotSection, 'g')
736+
plt.plot(1e-3 * X[0, :], self.landIceDraft, 'r')
721737

722738
ax.autoscale(tight=True)
723739
x1, x2, y1, y2 = 420, 470, -650, -520
@@ -729,6 +745,7 @@ def plot_layer_interfaces(self, figsize=(9, 5)):
729745
axins.plot(1e-3 * X[z_index, :], Z[z_index, :], 'k')
730746
axins.plot(1e-3 * X[0, :], Z[0, :], 'b')
731747
axins.plot(1e-3 * X[0, :], self.zBotSection, 'g')
748+
axins.plot(1e-3 * X[0, :], self.landIceDraft, 'r')
732749
axins.set_xlim(x1, x2)
733750
axins.set_ylim(y1, y2)
734751
axins.set_xticklabels([])
@@ -793,7 +810,7 @@ def update_date(self, tIndex):
793810
def _plot_horiz_field(self, field, title, outFileName, oceanDomain=True,
794811
vmin=None, vmax=None, figsize=(9, 3), cmap=None,
795812
cmap_set_under=None, cmap_set_over=None,
796-
cmap_scale='linear'):
813+
cmap_scale='linear', contour_field=None):
797814

798815
try:
799816
os.makedirs(os.path.dirname(outFileName))
@@ -824,10 +841,21 @@ def _plot_horiz_field(self, field, title, outFileName, oceanDomain=True,
824841
if cmap_scale == 'log':
825842
localPatches.set_norm(LogNorm(vmin=max(1e-10, vmin),
826843
vmax=vmax, clip=False))
844+
elif cmap_scale == 'symlog':
845+
localPatches.set_norm(SymLogNorm(vmin=vmin, vmax=vmax, clip=False,
846+
linthresh=vmax / 1e2))
827847

828848
plt.figure(figsize=figsize)
829849
ax = plt.subplot(111)
830850
ax.add_collection(localPatches)
851+
if contour_field is not None:
852+
dsMesh = self.dsMesh
853+
ax.tricontour(dsMesh.xCell / 1.e3, dsMesh.yCell / 1.e3,
854+
contour_field,
855+
colors='k', levels=[1.1e-2 + 1.e-8])
856+
ax.tricontour(dsMesh.xCell / 1.e3, dsMesh.yCell / 1.e3,
857+
contour_field,
858+
colors='grey', levels=numpy.arange(50., 700., 50.))
831859
plt.colorbar(localPatches, extend='both')
832860
plt.axis([0, 500, 0, 1000])
833861
ax.set_aspect('equal')
@@ -839,7 +867,7 @@ def _plot_horiz_field(self, field, title, outFileName, oceanDomain=True,
839867

840868
def _plot_vert_field(self, inX, inZ, field, title, outFileName,
841869
vmin=None, vmax=None, figsize=(9, 5), cmap=None,
842-
show_boundaries=True):
870+
show_boundaries=True, cmap_scale='linear'):
843871
try:
844872
os.makedirs(os.path.dirname(outFileName))
845873
except OSError:
@@ -850,24 +878,40 @@ def _plot_vert_field(self, inX, inZ, field, title, outFileName,
850878

851879
plt.figure(figsize=figsize)
852880
ax = plt.subplot(111)
853-
if show_boundaries:
854-
z_mask = numpy.ones(self.X.shape)
855-
z_mask[0:-1, 0:-1] *= numpy.where(self.sectionMask, 1., numpy.nan)
881+
z_mask = numpy.ones(self.X.shape)
882+
z_mask[0:-1, 0:-1] *= numpy.where(self.sectionMask, 1., numpy.nan)
856883

857-
tIndex = 0
858-
Z = numpy.array(self.Z[tIndex, :, :])
859-
Z *= z_mask
860-
X = self.X
884+
tIndex = 0
885+
Z = numpy.array(self.Z[tIndex, :, :])
886+
Z *= z_mask
887+
X = self.X
861888

862-
plt.fill_between(1e-3 * X[0, :], self.zBotSection, y2=0,
863-
facecolor='lightsteelblue', zorder=2)
864-
plt.fill_between(1e-3 * X[0, :], self.zBotSection, y2=-750,
865-
facecolor='grey', zorder=1)
889+
plt.fill_between(1e-3 * X[0, :], self.zBotSection, y2=0,
890+
facecolor='lightsteelblue', zorder=2)
891+
plt.fill_between(1e-3 * X[0, :], self.zBotSection, y2=-750,
892+
facecolor='grey', zorder=1)
893+
if show_boundaries:
866894
for z_index in range(1, X.shape[0]):
867895
plt.plot(1e-3 * X[z_index, :], Z[z_index, :], 'k', zorder=4)
868896
plt.pcolormesh(1e-3 * inX, inZ, field, vmin=vmin, vmax=vmax, cmap=cmap,
869897
zorder=3)
870898
plt.colorbar()
899+
x1, x2, y1, y2 = 455, 470, -640, -540
900+
axins = ax.inset_axes([0.01, 0.6, 0.3, 0.39])
901+
axins.fill_between(1e-3 * X[0, :], self.zBotSection, y2=0,
902+
facecolor='lightsteelblue', zorder=2)
903+
axins.fill_between(1e-3 * X[0, :], self.zBotSection, y2=-750,
904+
facecolor='grey', zorder=1)
905+
if show_boundaries:
906+
for z_index in range(1, X.shape[0]):
907+
axins.plot(1e-3 * X[z_index, :], Z[z_index, :], 'k', zorder=4)
908+
axins.pcolormesh(1e-3 * inX, inZ, field, vmin=vmin, vmax=vmax,
909+
cmap=cmap, zorder=3)
910+
axins.set_xlim(x1, x2)
911+
axins.set_ylim(y1, y2)
912+
axins.set_xticklabels([])
913+
axins.set_yticklabels([])
914+
ax.indicate_inset_zoom(axins, edgecolor="black")
871915
ax.autoscale(tight=True)
872916
plt.ylim([numpy.amin(inZ), 20])
873917
plt.xlim([400, 800])
@@ -918,6 +962,15 @@ def _compute_section_x_z(self):
918962
layerThickness[:, zIndex])
919963
self.Z[tIndex, zIndex, :] = self.Z[tIndex, zIndex + 1, :] + \
920964
layerThicknessSection
965+
if 'timeMonthly_avg_landIceDraft' in self.ds:
966+
var = 'timeMonthly_avg_landIceDraft'
967+
else:
968+
var = 'landIceDraft'
969+
landIceDraft = self.ds[var].isel(
970+
Time=tIndex, nCells=self.sectionCellIndices)
971+
landIceDraft = landIceDraft.values * self.sectionMask[0, :].T
972+
landIceDraft = numpy.nan_to_num(landIceDraft)
973+
self.landIceDraft = _interp_extrap_corner(landIceDraft)
921974

922975

923976
def _compute_cell_patches(dsMesh, mask):

0 commit comments

Comments
 (0)