Prominent British Mountains

metadata

In a former life I considered myself a mountaineer; recently I stumbled across The Database of British and Irish Hills (DoBIH) and it got me thinking about how many of them I have visited. In the UK a “mountain” is anything with an elevation over 600m. Below is a map of all of the mountains in the British Isles.

Download:
  1. 346 px × 512 px (0.2 Mpx; 90.1 KiB)
  2. 692 px × 1,024 px (0.7 Mpx; 287.3 KiB)
  3. 1,385 px × 2,048 px (2.8 Mpx; 943.8 KiB)
  4. 1,971 px × 2,915 px (5.7 Mpx; 1.5 MiB)

As you can see, the vast majority of them are in Scotland.

Below is a map of all of the mountains over 900m in the British Isles.

Download:
  1. 346 px × 512 px (0.2 Mpx; 77.9 KiB)
  2. 692 px × 1,024 px (0.7 Mpx; 245.7 KiB)
  3. 1,385 px × 2,048 px (2.8 Mpx; 799.2 KiB)
  4. 1,971 px × 2,915 px (5.7 Mpx; 1.4 MiB)

Once again, the vast majority are in Scotland. Furthermore, the only ones in England are in The Lake District.

Recently, I have become interested in the idea of the prominence of mountains as a metric for is it worth climbing? Wikipedia has a list of all of the mountains in the British Isles with a prominence over 600m. Using The Database of British and Irish Hills (DoBIH) I wrote a Python script to create a map of these prominent mountains, which is shown below.

Download:
  1. 346 px × 512 px (0.2 Mpx; 78.0 KiB)
  2. 692 px × 1,024 px (0.7 Mpx; 241.1 KiB)
  3. 1,385 px × 2,048 px (2.8 Mpx; 777.2 KiB)
  4. 1,971 px × 2,915 px (5.7 Mpx; 1.3 MiB)

As you can see, adding a prominence filter on top of the elevation filter really starts to curtail the list of mountains in the British Isles: there are only 7 in Wales; and there are only 4 in England.

Finally, to be really strict, I created a map and table (shown below) of all of the mountains in the British Isles with a prominence over 900m.

Download:
  1. 346 px × 512 px (0.2 Mpx; 72.9 KiB)
  2. 692 px × 1,024 px (0.7 Mpx; 230.7 KiB)
  3. 1,385 px × 2,048 px (2.8 Mpx; 749.7 KiB)
  4. 1,971 px × 2,915 px (5.7 Mpx; 1.3 MiB)
Mountain Elevation [m] Prominence [m]
Ben More 1,174.0 986.0
Ben Lawers 1,214.0 915.0
Ben Nevis 1,344.5 1,344.5
Ben Macdui 1,309.0 950.0
Carn Eighe 1,182.8 1,147.0
Liathach - Spidean a’ Choire Leith 1,054.8 957.0
Sgurr Mor 1,108.9 914.0
Sgurr Alasdair 992.0 992.0
Ben More 966.0 966.0
Snowdon - Yr Wyddfa 1,085.0 1,039.0
Scafell Pike 978.1 912.0
Carrauntoohil 1,038.6 1,038.6
Brandon Mountain 951.7 927.0

This seems like a decent “bucket list” doesn’t it?

Below you will find the four Python scripts that I wrote to generate these four maps, enjoy!

001: #!/usr/bin/env python3
002: 
003: # NOTE: "The Database of British and Irish Hills" can be visited here:
004: #         * http://www.hills-database.co.uk/
005: #       ... and the links to download the database can be found here:
006: #         * http://www.hills-database.co.uk/downloads.html
007: 
008: # Import standard modules ...
009: import csv
010: import json
011: import os
012: import zipfile
013: 
014: # Import special modules ...
015: try:
016:     import cartopy
017:     import cartopy.crs
018: except:
019:     raise Exception("\"cartopy\" is not installed; run \"pip install --user Cartopy\"") from None
020: try:
021:     import matplotlib
022:     matplotlib.use("Agg")                                                       # NOTE: See https://matplotlib.org/stable/gallery/user_interfaces/canvasagg.html
023:     import matplotlib.pyplot
024: except:
025:     raise Exception("\"matplotlib\" is not installed; run \"pip install --user matplotlib\"") from None
026: try:
027:     import numpy
028: except:
029:     raise Exception("\"numpy\" is not installed; run \"pip install --user numpy\"") from None
030: 
031: # Import my modules ...
032: try:
033:     import pyguymer3
034:     import pyguymer3.image
035: except:
036:     raise Exception("\"pyguymer3\" is not installed; you need to have the Python module from https://github.com/Guymer/PyGuymer3 located somewhere in your $PYTHONPATH") from None
037: 
038: # ******************************************************************************
039: 
040: # Start session ...
041: sess = pyguymer3.start_session()
042: 
043: # Check if the database is missing ...
044: if not os.path.exists("hillcsv.zip"):
045:     # Download the database ...
046:     pyguymer3.download_file(sess, "http://www.hills-database.co.uk/hillcsv.zip", "hillcsv.zip")
047: 
048: # ******************************************************************************
049: 
050: # Initialize counter ...
051: n = 0                                                                           # [#]
052: 
053: # Initialize lists ...
054: x = []                                                                          # [°]
055: y = []                                                                          # [°]
056: z = []                                                                          # [m]
057: 
058: # Open output file ...
059: with open("british-hills-E600.txt", "wt", encoding = "utf-8") as fobjOut:
060:     # Open input file ...
061:     with zipfile.ZipFile("hillcsv.zip", "r") as fobjIn:
062:         # Loop over members ...
063:         for fname in fobjIn.namelist():
064:             # Skip those that are not CSVs ...
065:             if not fname.endswith(".csv"):
066:                 continue
067: 
068:             # Read CSV dataset as a list of strings ...
069:             rows = fobjIn.read(fname).decode("ascii").splitlines()
070: 
071:             # Loop over rows ...
072:             for row in csv.DictReader(rows):
073:                 # Skip this row if the elevation is too small ...
074:                 if float(row["Metres"]) < 600.0:
075:                     continue
076: 
077:                 # Increment counter ...
078:                 n += 1                                                          # [#]
079: 
080:                 # Append to lists ...
081:                 x.append(float(row["Longitude"]))                               # [°]
082:                 y.append(float(row["Latitude"]))                                # [°]
083:                 z.append(float(row["Metres"]))                                  # [m]
084: 
085:                 # Write summary ...
086:                 fobjOut.write(f'"{row["Name"]}" is {float(row["Metres"]):,.1f}m ASL with a prominence of {float(row["Drop"]):,.1f}m at ({float(row["Latitude"]):f}°,{float(row["Longitude"]):f}°).\n')
087: 
088: # Print summary ...
089: print(f"There are {n:,d} E600 mountains in The British Isles.")
090: 
091: # ******************************************************************************
092: 
093: # Load tile metadata ...
094: with open("OrdnanceSurveyBackgroundImages/miniscale.json", "rt", encoding = "utf-8") as fobj:
095:     meta = json.load(fobj)
096: 
097: # Convert lists to arrays and find the sorted keys ...
098: x = numpy.array(x)                                                              # [°]
099: y = numpy.array(y)                                                              # [°]
100: z = numpy.array(z)                                                              # [m]
101: k = numpy.argsort(z)
102: 
103: # Create figure ...
104: # NOTE: If "transform" is not subsequently supplied then it is assumed to be
105: #       "cartopy.crs.OSGB()" as that is what the axes are.
106: fg = matplotlib.pyplot.figure(figsize = (8, 12), dpi = 300)
107: ax = matplotlib.pyplot.axes(projection = cartopy.crs.OSGB())
108: 
109: # Add background image ...
110: ax.imshow(
111:     matplotlib.pyplot.imread(f'OrdnanceSurveyBackgroundImages/{meta["MiniScale_(mono)_R22"]["greyscale"]}'),
112:     cmap = "gray",
113:     extent = meta["MiniScale_(mono)_R22"]["extent"],
114:     interpolation = "bicubic",
115:     origin = "upper",
116:     vmin = 0.0,
117:     vmax = 1.0
118: )
119: 
120: # Plot data (layering them correctly) and add colour bar ...
121: sc = ax.scatter(
122:     x[k],
123:     y[k],
124:     s = 10.0,
125:     c = z[k],
126:     linewidth = 0.1,
127:     edgecolors = "black",
128:     cmap = matplotlib.pyplot.cm.rainbow,
129:     vmin = 600.0,
130:     transform = cartopy.crs.PlateCarree()
131: )
132: cb = fg.colorbar(sc)
133: 
134: # Configure axes ...
135: ax.set_title("E600 Mountains In The British Isles")
136: 
137: # Configure color bar ...
138: cb.set_label("Elevation [m]")
139: 
140: # Save figure ...
141: fg.savefig("british-hills-E600.png", bbox_inches = "tight", dpi = 300, pad_inches = 0.1)
142: matplotlib.pyplot.close(fg)
143: pyguymer3.image.optimize_image("british-hills-E600.png", strip = True)
144: 
You may also download “british-hills-E600.py” directly or view “british-hills-E600.py” on GitHub Gist.
001: #!/usr/bin/env python3
002: 
003: # NOTE: "The Database of British and Irish Hills" can be visited here:
004: #         * http://www.hills-database.co.uk/
005: #       ... and the links to download the database can be found here:
006: #         * http://www.hills-database.co.uk/downloads.html
007: 
008: # Import standard modules ...
009: import csv
010: import json
011: import os
012: import zipfile
013: 
014: # Import special modules ...
015: try:
016:     import cartopy
017:     import cartopy.crs
018: except:
019:     raise Exception("\"cartopy\" is not installed; run \"pip install --user Cartopy\"") from None
020: try:
021:     import matplotlib
022:     matplotlib.use("Agg")                                                       # NOTE: See https://matplotlib.org/stable/gallery/user_interfaces/canvasagg.html
023:     import matplotlib.pyplot
024: except:
025:     raise Exception("\"matplotlib\" is not installed; run \"pip install --user matplotlib\"") from None
026: try:
027:     import numpy
028: except:
029:     raise Exception("\"numpy\" is not installed; run \"pip install --user numpy\"") from None
030: 
031: # Import my modules ...
032: try:
033:     import pyguymer3
034:     import pyguymer3.image
035: except:
036:     raise Exception("\"pyguymer3\" is not installed; you need to have the Python module from https://github.com/Guymer/PyGuymer3 located somewhere in your $PYTHONPATH") from None
037: 
038: # ******************************************************************************
039: 
040: # Start session ...
041: sess = pyguymer3.start_session()
042: 
043: # Check if the database is missing ...
044: if not os.path.exists("hillcsv.zip"):
045:     # Download the database ...
046:     pyguymer3.download_file(sess, "http://www.hills-database.co.uk/hillcsv.zip", "hillcsv.zip")
047: 
048: # ******************************************************************************
049: 
050: # Initialize counter ...
051: n = 0                                                                           # [#]
052: 
053: # Initialize lists ...
054: x = []                                                                          # [°]
055: y = []                                                                          # [°]
056: z = []                                                                          # [m]
057: 
058: # Open output file ...
059: with open("british-hills-E900.txt", "wt", encoding = "utf-8") as fobjOut:
060:     # Open input file ...
061:     with zipfile.ZipFile("hillcsv.zip", "r") as fobjIn:
062:         # Loop over members ...
063:         for fname in fobjIn.namelist():
064:             # Skip those that are not CSVs ...
065:             if not fname.endswith(".csv"):
066:                 continue
067: 
068:             # Read CSV dataset as a list of strings ...
069:             rows = fobjIn.read(fname).decode("ascii").splitlines()
070: 
071:             # Loop over rows ...
072:             for row in csv.DictReader(rows):
073:                 # Skip this row if the elevation is too small ...
074:                 if float(row["Metres"]) < 900.0:
075:                     continue
076: 
077:                 # Increment counter ...
078:                 n += 1                                                          # [#]
079: 
080:                 # Append to lists ...
081:                 x.append(float(row["Longitude"]))                               # [°]
082:                 y.append(float(row["Latitude"]))                                # [°]
083:                 z.append(float(row["Metres"]))                                  # [m]
084: 
085:                 # Write summary ...
086:                 fobjOut.write(f'"{row["Name"]}" is {float(row["Metres"]):,.1f}m ASL with a prominence of {float(row["Drop"]):,.1f}m at ({float(row["Latitude"]):f}°,{float(row["Longitude"]):f}°).\n')
087: 
088: # Print summary ...
089: print(f"There are {n:,d} E900 mountains in The British Isles.")
090: 
091: # ******************************************************************************
092: 
093: # Load tile metadata ...
094: with open("OrdnanceSurveyBackgroundImages/miniscale.json", "rt", encoding = "utf-8") as fobj:
095:     meta = json.load(fobj)
096: 
097: # Convert lists to arrays and find the sorted keys ...
098: x = numpy.array(x)                                                              # [°]
099: y = numpy.array(y)                                                              # [°]
100: z = numpy.array(z)                                                              # [m]
101: k = numpy.argsort(z)
102: 
103: # Create figure ...
104: # NOTE: If "transform" is not subsequently supplied then it is assumed to be
105: #       "cartopy.crs.OSGB()" as that is what the axes are.
106: fg = matplotlib.pyplot.figure(figsize = (8, 12), dpi = 300)
107: ax = matplotlib.pyplot.axes(projection = cartopy.crs.OSGB())
108: 
109: # Add background image ...
110: ax.imshow(
111:     matplotlib.pyplot.imread(f'OrdnanceSurveyBackgroundImages/{meta["MiniScale_(mono)_R22"]["greyscale"]}'),
112:     cmap = "gray",
113:     extent = meta["MiniScale_(mono)_R22"]["extent"],
114:     interpolation = "bicubic",
115:     origin = "upper",
116:     vmin = 0.0,
117:     vmax = 1.0
118: )
119: 
120: # Plot data (layering them correctly) and add colour bar ...
121: sc = ax.scatter(
122:     x[k],
123:     y[k],
124:     s = 10.0,
125:     c = z[k],
126:     linewidth = 0.1,
127:     edgecolors = "black",
128:     cmap = matplotlib.pyplot.cm.rainbow,
129:     vmin = 900.0,
130:     transform = cartopy.crs.PlateCarree()
131: )
132: cb = fg.colorbar(sc)
133: 
134: # Configure axes ...
135: ax.set_title("E900 Mountains In The British Isles")
136: 
137: # Configure color bar ...
138: cb.set_label("Elevation [m]")
139: 
140: # Save figure ...
141: fg.savefig("british-hills-E900.png", bbox_inches = "tight", dpi = 300, pad_inches = 0.1)
142: matplotlib.pyplot.close(fg)
143: pyguymer3.image.optimize_image("british-hills-E900.png", strip = True)
144: 
You may also download “british-hills-E900.py” directly or view “british-hills-E900.py” on GitHub Gist.
001: #!/usr/bin/env python3
002: 
003: # NOTE: "The Database of British and Irish Hills" can be visited here:
004: #         * http://www.hills-database.co.uk/
005: #       ... and the links to download the database can be found here:
006: #         * http://www.hills-database.co.uk/downloads.html
007: # NOTE: https://en.wikipedia.org/wiki/List_of_P600_mountains_in_the_British_Isles
008: 
009: # Import standard modules ...
010: import csv
011: import json
012: import os
013: import zipfile
014: 
015: # Import special modules ...
016: try:
017:     import cartopy
018:     import cartopy.crs
019: except:
020:     raise Exception("\"cartopy\" is not installed; run \"pip install --user Cartopy\"") from None
021: try:
022:     import matplotlib
023:     matplotlib.use("Agg")                                                       # NOTE: See https://matplotlib.org/stable/gallery/user_interfaces/canvasagg.html
024:     import matplotlib.pyplot
025: except:
026:     raise Exception("\"matplotlib\" is not installed; run \"pip install --user matplotlib\"") from None
027: try:
028:     import numpy
029: except:
030:     raise Exception("\"numpy\" is not installed; run \"pip install --user numpy\"") from None
031: 
032: # Import my modules ...
033: try:
034:     import pyguymer3
035:     import pyguymer3.image
036: except:
037:     raise Exception("\"pyguymer3\" is not installed; you need to have the Python module from https://github.com/Guymer/PyGuymer3 located somewhere in your $PYTHONPATH") from None
038: 
039: # ******************************************************************************
040: 
041: # Start session ...
042: sess = pyguymer3.start_session()
043: 
044: # Check if the database is missing ...
045: if not os.path.exists("hillcsv.zip"):
046:     # Download the database ...
047:     pyguymer3.download_file(sess, "http://www.hills-database.co.uk/hillcsv.zip", "hillcsv.zip")
048: 
049: # ******************************************************************************
050: 
051: # Initialize counter ...
052: n = 0                                                                           # [#]
053: 
054: # Initialize lists ...
055: x = []                                                                          # [°]
056: y = []                                                                          # [°]
057: z = []                                                                          # [m]
058: 
059: # Open output file ...
060: with open("british-hills-P600.txt", "wt", encoding = "utf-8") as fobjOut:
061:     # Open input file ...
062:     with zipfile.ZipFile("hillcsv.zip", "r") as fobjIn:
063:         # Loop over members ...
064:         for fname in fobjIn.namelist():
065:             # Skip those that are not CSVs ...
066:             if not fname.endswith(".csv"):
067:                 continue
068: 
069:             # Read CSV dataset as a list of strings ...
070:             rows = fobjIn.read(fname).decode("ascii").splitlines()
071: 
072:             # Loop over rows ...
073:             for row in csv.DictReader(rows):
074:                 # Skip this row if the prominence is too small ...
075:                 if float(row["Drop"]) < 600.0:
076:                     continue
077: 
078:                 # Increment counter ...
079:                 n += 1                                                          # [#]
080: 
081:                 # Append to lists ...
082:                 x.append(float(row["Longitude"]))                               # [°]
083:                 y.append(float(row["Latitude"]))                                # [°]
084:                 z.append(float(row["Drop"]))                                    # [m]
085: 
086:                 # Write summary ...
087:                 fobjOut.write(f'"{row["Name"]}" is {float(row["Metres"]):,.1f}m ASL with a prominence of {float(row["Drop"]):,.1f}m at ({float(row["Latitude"]):f}°,{float(row["Longitude"]):f}°).\n')
088: 
089: # Print summary ...
090: print(f"There are {n:,d} P600 mountains in The British Isles.")
091: 
092: # ******************************************************************************
093: 
094: # Load tile metadata ...
095: with open("OrdnanceSurveyBackgroundImages/miniscale.json", "rt", encoding = "utf-8") as fobj:
096:     meta = json.load(fobj)
097: 
098: # Convert lists to arrays and find the sorted keys ...
099: x = numpy.array(x)                                                              # [°]
100: y = numpy.array(y)                                                              # [°]
101: z = numpy.array(z)                                                              # [m]
102: k = numpy.argsort(z)
103: 
104: # Create figure ...
105: # NOTE: If "transform" is not subsequently supplied then it is assumed to be
106: #       "cartopy.crs.OSGB()" as that is what the axes are.
107: fg = matplotlib.pyplot.figure(figsize = (8, 12), dpi = 300)
108: ax = matplotlib.pyplot.axes(projection = cartopy.crs.OSGB())
109: 
110: # Add background image ...
111: ax.imshow(
112:     matplotlib.pyplot.imread(f'OrdnanceSurveyBackgroundImages/{meta["MiniScale_(mono)_R22"]["greyscale"]}'),
113:     cmap = "gray",
114:     extent = meta["MiniScale_(mono)_R22"]["extent"],
115:     interpolation = "bicubic",
116:     origin = "upper",
117:     vmin = 0.0,
118:     vmax = 1.0
119: )
120: 
121: # Plot data (layering them correctly) and add colour bar ...
122: sc = ax.scatter(
123:     x[k],
124:     y[k],
125:     s = 10.0,
126:     c = z[k],
127:     linewidth = 0.1,
128:     edgecolors = "black",
129:     cmap = matplotlib.pyplot.cm.rainbow,
130:     vmin = 600.0,
131:     transform = cartopy.crs.PlateCarree()
132: )
133: cb = fg.colorbar(sc)
134: 
135: # Configure axes ...
136: ax.set_title("P600 Mountains In The British Isles")
137: 
138: # Configure color bar ...
139: cb.set_label("Prominence [m]")
140: 
141: # Save figure ...
142: fg.savefig("british-hills-P600.png", bbox_inches = "tight", dpi = 300, pad_inches = 0.1)
143: matplotlib.pyplot.close(fg)
144: pyguymer3.image.optimize_image("british-hills-P600.png", strip = True)
145: 
You may also download “british-hills-P600.py” directly or view “british-hills-P600.py” on GitHub Gist.
001: #!/usr/bin/env python3
002: 
003: # NOTE: "The Database of British and Irish Hills" can be visited here:
004: #         * http://www.hills-database.co.uk/
005: #       ... and the links to download the database can be found here:
006: #         * http://www.hills-database.co.uk/downloads.html
007: 
008: # Import standard modules ...
009: import csv
010: import json
011: import os
012: import zipfile
013: 
014: # Import special modules ...
015: try:
016:     import cartopy
017:     import cartopy.crs
018: except:
019:     raise Exception("\"cartopy\" is not installed; run \"pip install --user Cartopy\"") from None
020: try:
021:     import matplotlib
022:     matplotlib.use("Agg")                                                       # NOTE: See https://matplotlib.org/stable/gallery/user_interfaces/canvasagg.html
023:     import matplotlib.pyplot
024: except:
025:     raise Exception("\"matplotlib\" is not installed; run \"pip install --user matplotlib\"") from None
026: try:
027:     import numpy
028: except:
029:     raise Exception("\"numpy\" is not installed; run \"pip install --user numpy\"") from None
030: 
031: # Import my modules ...
032: try:
033:     import pyguymer3
034:     import pyguymer3.image
035: except:
036:     raise Exception("\"pyguymer3\" is not installed; you need to have the Python module from https://github.com/Guymer/PyGuymer3 located somewhere in your $PYTHONPATH") from None
037: 
038: # ******************************************************************************
039: 
040: # Start session ...
041: sess = pyguymer3.start_session()
042: 
043: # Check if the database is missing ...
044: if not os.path.exists("hillcsv.zip"):
045:     # Download the database ...
046:     pyguymer3.download_file(sess, "http://www.hills-database.co.uk/hillcsv.zip", "hillcsv.zip")
047: 
048: # ******************************************************************************
049: 
050: # Initialize counter ...
051: n = 0                                                                           # [#]
052: 
053: # Initialize lists ...
054: x = []                                                                          # [°]
055: y = []                                                                          # [°]
056: z = []                                                                          # [m]
057: 
058: # Open output file ...
059: with open("british-hills-P900.txt", "wt", encoding = "utf-8") as fobjOut:
060:     # Open input file ...
061:     with zipfile.ZipFile("hillcsv.zip", "r") as fobjIn:
062:         # Loop over members ...
063:         for fname in fobjIn.namelist():
064:             # Skip those that are not CSVs ...
065:             if not fname.endswith(".csv"):
066:                 continue
067: 
068:             # Read CSV dataset as a list of strings ...
069:             rows = fobjIn.read(fname).decode("ascii").splitlines()
070: 
071:             # Loop over rows ...
072:             for row in csv.DictReader(rows):
073:                 # Skip this row if the prominence is too small ...
074:                 if float(row["Drop"]) < 900.0:
075:                     continue
076: 
077:                 # Increment counter ...
078:                 n += 1                                                          # [#]
079: 
080:                 # Append to lists ...
081:                 x.append(float(row["Longitude"]))                               # [°]
082:                 y.append(float(row["Latitude"]))                                # [°]
083:                 z.append(float(row["Drop"]))                                    # [m]
084: 
085:                 # Write summary ...
086:                 fobjOut.write(f'"{row["Name"]}" is {float(row["Metres"]):,.1f}m ASL with a prominence of {float(row["Drop"]):,.1f}m at ({float(row["Latitude"]):f}°,{float(row["Longitude"]):f}°).\n')
087: 
088: # Print summary ...
089: print(f"There are {n:,d} P900 mountains in The British Isles.")
090: 
091: # ******************************************************************************
092: 
093: # Load tile metadata ...
094: with open("OrdnanceSurveyBackgroundImages/miniscale.json", "rt", encoding = "utf-8") as fobj:
095:     meta = json.load(fobj)
096: 
097: # Convert lists to arrays and find the sorted keys ...
098: x = numpy.array(x)                                                              # [°]
099: y = numpy.array(y)                                                              # [°]
100: z = numpy.array(z)                                                              # [m]
101: k = numpy.argsort(z)
102: 
103: # Create figure ...
104: # NOTE: If "transform" is not subsequently supplied then it is assumed to be
105: #       "cartopy.crs.OSGB()" as that is what the axes are.
106: fg = matplotlib.pyplot.figure(figsize = (8, 12), dpi = 300)
107: ax = matplotlib.pyplot.axes(projection = cartopy.crs.OSGB())
108: 
109: # Add background image ...
110: ax.imshow(
111:     matplotlib.pyplot.imread(f'OrdnanceSurveyBackgroundImages/{meta["MiniScale_(mono)_R22"]["greyscale"]}'),
112:     cmap = "gray",
113:     extent = meta["MiniScale_(mono)_R22"]["extent"],
114:     interpolation = "bicubic",
115:     origin = "upper",
116:     vmin = 0.0,
117:     vmax = 1.0
118: )
119: 
120: # Plot data (layering them correctly) and add colour bar ...
121: sc = ax.scatter(
122:     x[k],
123:     y[k],
124:     s = 10.0,
125:     c = z[k],
126:     linewidth = 0.1,
127:     edgecolors = "black",
128:     cmap = matplotlib.pyplot.cm.rainbow,
129:     vmin = 900.0,
130:     transform = cartopy.crs.PlateCarree()
131: )
132: cb = fg.colorbar(sc)
133: 
134: # Configure axes ...
135: ax.set_title("P900 Mountains In The British Isles")
136: 
137: # Configure color bar ...
138: cb.set_label("Prominence [m]")
139: 
140: # Save figure ...
141: fg.savefig("british-hills-P900.png", bbox_inches = "tight", dpi = 300, pad_inches = 0.1)
142: matplotlib.pyplot.close(fg)
143: pyguymer3.image.optimize_image("british-hills-P900.png", strip = True)
144: 
You may also download “british-hills-P900.py” directly or view “british-hills-P900.py” on GitHub Gist.