Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions docs/gallery_code/meteorology/plot_zonal_mean.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""
Zonal Mean Diagram of Air Temperature
=====================================

This example demonstrates aligning a linear plot and a cartographic plot using Matplotlib.

"""

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np

import iris
from iris.analysis import MEAN
import iris.plot as iplt


def main():
fname = iris.sample_data_path("air_temp.pp")
temperature = iris.load_cube(fname)
collapsed_temp = temperature.collapsed("longitude", MEAN)

# Set y axes with -90 and 90 limits and spacing of 15 per tick.
yticks = np.arange(-90, 105, 15)
ylim = [-90, 90]
fig = plt.figure(figsize=[12, 4])
Comment on lines +24 to +27
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This deserves its own code block, as it's not directly related to the following code.

Suggested change
# Set y axes with -90 and 90 limits and spacing of 15 per tick.
yticks = np.arange(-90, 105, 15)
ylim = [-90, 90]
fig = plt.figure(figsize=[12, 4])
# Set y axes with -90 and 90 limits and spacing of 15 per tick.
yticks = np.arange(-90, 105, 15)
ylim = [-90, 90]
# Plot "temperature" on a cartographic plot and set the ticks and titles on the axes.
fig = plt.figure(figsize=[12, 4])

ax1 = fig.add_subplot(111, projection=ccrs.PlateCarree())
plt.sca(ax1)
im = iplt.contourf(temperature, cmap="RdYlBu_r")
ax1.coastlines()
ax1.gridlines()
ax1.set_xticks([-180, -90, 0, 90, 180], crs=ccrs.PlateCarree())
ax1.set_yticks(yticks, crs=ccrs.PlateCarree())
ax1.set_title("Air Temperature")
ax1.set_ylabel("latitude")
ax1.set_xlabel("longitude")
ax1.set_ylim(*ylim)
divider = make_axes_locatable(ax1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the 'magic sauce' that makes it possible to align everything, so it should have some extra emphasis. I've done a bit of reading to work out an appropriate comment:

Suggested change
divider = make_axes_locatable(ax1)
# Create a Matplotlib AxesDivider object to allow alignment of other Axes objects.
divider = make_axes_locatable(ax1)


# Gives the air temperature bar size, colour and a title.
ax2 = divider.new_vertical(
size="5%", pad=0.5, axes_class=plt.Axes, pack_start=True
)
fig.add_axes(ax2)
plt.sca(ax2)
cbar = plt.colorbar(im, cax=ax2, orientation="horizontal")
cbar.ax.set_xlabel("Air Temperature [k]")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cbar.ax.set_xlabel("Air Temperature [k]")
cbar.ax.set_xlabel("Air Temperature [K]")

Reference


# Round each tick for the third ax to the nearest 20 (ready for use).
data_max = collapsed_temp.data.max()
x_max = data_max - data_max % -20
data_min = collapsed_temp.data.min()
x_min = data_min - data_min % 20
Comment on lines +50 to +54
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could move this block after the ax3 block so that it can include the ax3.set_xlim(x_min, x_max) line, too.


# Plot "collapsed_temp" on the mean graph and set the ticks and titles on the axes.
ax3 = divider.new_horizontal(size="30%", pad=0.4, axes_class=plt.Axes)
fig.add_axes(ax3)
plt.sca(ax3)
iplt.plot(collapsed_temp, collapsed_temp.coord("latitude"))
ax3.axvline(0, color="k", linewidth=0.5)
ax3.set_ylim(*ylim)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swap position with ax3.set_yticks(yticks) - for consistency with the ax1 block.

ax3.set_title("Zonal mean")
ax3.set_ylabel("latitude")
ax3.set_xlabel("Air Temperature [k]")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ax3.set_xlabel("Air Temperature [k]")
ax3.set_xlabel("Air Temperature [K]")

Reference

ax3.yaxis.set_label_position("right")
ax3.yaxis.tick_right()
ax3.set_yticks(yticks)
ax3.set_xlim(x_min, x_max)

plt.show()


if __name__ == "__main__":
main()
30 changes: 30 additions & 0 deletions docs/gallery_tests/test_plot_zonal_mean.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright Iris contributors
#
# This file is part of Iris and is released under the LGPL license.
# See COPYING and COPYING.LESSER in the root of the repository for full
# licensing details.

# Import Iris tests first so that some things can be initialised before
# importing anything else.
import iris.tests as tests

from .gallerytest_util import (
add_gallery_to_path,
fail_any_deprecation_warnings,
show_replaced_by_check_graphic,
)


class TestGlobalMap(tests.GraphicsTest):
"""Test the zonal mean gallery code."""

def test_plot_zonal_mean(self):
with fail_any_deprecation_warnings():
with add_gallery_to_path():
import plot_zonal_mean
with show_replaced_by_check_graphic(self):
plot_zonal_mean.main()


if __name__ == "__main__":
tests.main()
9 changes: 7 additions & 2 deletions docs/src/whatsnew/latest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ This document explains the changes made to Iris for this release
📢 Announcements
================

#. N/A
#. Welcome to `@TTV-Intrepid`_ who made their first contribution to Iris.
The first of many we hope!


✨ Features
Expand Down Expand Up @@ -217,6 +218,9 @@ This document explains the changes made to Iris for this release
#. `@trexfeathers`_ and `@abooton`_ modernised the Iris logo to be SVG format.
(:pull:`3935`)

#. `@TTV-Intrepid`_ and `@trexfeathers`_ added a gallery example for zonal
means plotted parallel to a cartographic plot. (:pull:`4871`)


💼 Internal
===========
Expand Down Expand Up @@ -268,4 +272,5 @@ This document explains the changes made to Iris for this release
.. _Calendar: https://cfconventions.org/Data/cf-conventions/cf-conventions-1.9/cf-conventions.html#calendar
.. _Cell Boundaries: https://cfconventions.org/Data/cf-conventions/cf-conventions-1.9/cf-conventions.html#cell-boundaries
.. _PyData Sphinx Theme: https://pydata-sphinx-theme.readthedocs.io/en/stable/index.html
.. _setuptools-scm: https://github.com/pypa/setuptools_scm
.. _setuptools-scm: https://github.com/pypa/setuptools_scm
.. _@TTV-Intrepid: https://github.com/TTV-Intrepid
1 change: 1 addition & 0 deletions lib/iris/tests/results/imagerepo.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"gallery_tests.test_plot_wind_barbs.TestWindBarbs.test_wind_barbs.0": "e9e161e996169316c1fe9e96c29e36739e13c07c3d61c07f39813929c07f3f01",
"gallery_tests.test_plot_wind_speed.TestWindSpeed.test_plot_wind_speed.0": "e9e960e996169306c1fe9e96c29e36739e03c06c3d61c07f3da139e1c07f3f01",
"gallery_tests.test_plot_wind_speed.TestWindSpeed.test_plot_wind_speed.1": "e9e960e996169306c1ee9f96c29e36739653c06c3d61c07f39a139e1c07f3f01",
"gallery_tests.test_plot_zonal_mean.TestGlobalMap.test_plot_zonal_mean.0": "b45b30f3c924c9a6869c667cc326cba3cb9634ddc9a634f336738c6634d8c3c4",
"iris.tests.experimental.test_animate.IntegrationTest.test_cube_animation.0": "fe81c17e817e3e81817e3e81857e7a817e81c17e7e81c17e7a81817e817e8c2e",
"iris.tests.experimental.test_animate.IntegrationTest.test_cube_animation.1": "fe81857e817e7a85817e7a81857e7e817e81917a7e81817e7a81817e817e843e",
"iris.tests.experimental.test_animate.IntegrationTest.test_cube_animation.2": "be81817ec17e7a81c17e7e81857e3e803e81817a3e81c17e7a81c17ec97e2c2f",
Expand Down