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(
087:                     "\"{:s}\" is {:,.1f}m ASL with a prominence of {:,.1f}m at ({:f}°,{:f}°).\n".format(
088:                         row["Name"],
089:                         float(row["Metres"]),
090:                         float(row["Drop"]),
091:                         float(row["Latitude"]),
092:                         float(row["Longitude"])
093:                     )
094:                 )
095: 
096: # Print summary ...
097: print(f"There are {n:,d} E600 mountains in The British Isles.")
098: 
099: # ******************************************************************************
100: 
101: # Load tile metadata ...
102: meta = json.load(open("OrdnanceSurveyBackgroundImages/miniscale.json", "rt", encoding = "utf-8"))
103: 
104: # Convert lists to arrays and find the sorted keys ...
105: x = numpy.array(x)                                                              # [°]
106: y = numpy.array(y)                                                              # [°]
107: z = numpy.array(z)                                                              # [m]
108: k = numpy.argsort(z)
109: 
110: # Create figure ...
111: # NOTE: If "transform" is not subsequently supplied then it is assumed to be
112: #       "cartopy.crs.OSGB()" as that is what the axes are.
113: fg = matplotlib.pyplot.figure(figsize = (8, 12), dpi = 300)
114: ax = matplotlib.pyplot.axes(projection = cartopy.crs.OSGB())
115: 
116: # Add background image ...
117: ax.imshow(
118:     matplotlib.pyplot.imread(f'OrdnanceSurveyBackgroundImages/{meta["MiniScale_(mono)_R22"]["greyscale"]}'),
119:     cmap = "gray",
120:     extent = meta["MiniScale_(mono)_R22"]["extent"],
121:     interpolation = "bicubic",
122:     origin = "upper",
123:     vmin = 0.0,
124:     vmax = 1.0
125: )
126: 
127: # Plot data (layering them correctly) and add colour bar ...
128: sc = ax.scatter(
129:     x[k],
130:     y[k],
131:     s = 10.0,
132:     c = z[k],
133:     linewidth = 0.1,
134:     edgecolors = "black",
135:     cmap = matplotlib.pyplot.cm.rainbow,
136:     vmin = 600.0,
137:     transform = cartopy.crs.PlateCarree()
138: )
139: cb = fg.colorbar(sc)
140: 
141: # Configure axes ...
142: ax.set_title("E600 Mountains In The British Isles")
143: 
144: # Configure color bar ...
145: cb.set_label("Elevation [m]")
146: 
147: # Save figure ...
148: fg.savefig("british-hills-E600.png", bbox_inches = "tight", dpi = 300, pad_inches = 0.1)
149: matplotlib.pyplot.close(fg)
150: pyguymer3.image.optimize_image("british-hills-E600.png", strip = True)
151: 
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(
087:                     "\"{:s}\" is {:,.1f}m ASL with a prominence of {:,.1f}m at ({:f}°,{:f}°).\n".format(
088:                         row["Name"],
089:                         float(row["Metres"]),
090:                         float(row["Drop"]),
091:                         float(row["Latitude"]),
092:                         float(row["Longitude"])
093:                     )
094:                 )
095: 
096: # Print summary ...
097: print(f"There are {n:,d} E900 mountains in The British Isles.")
098: 
099: # ******************************************************************************
100: 
101: # Load tile metadata ...
102: meta = json.load(open("OrdnanceSurveyBackgroundImages/miniscale.json", "rt", encoding = "utf-8"))
103: 
104: # Convert lists to arrays and find the sorted keys ...
105: x = numpy.array(x)                                                              # [°]
106: y = numpy.array(y)                                                              # [°]
107: z = numpy.array(z)                                                              # [m]
108: k = numpy.argsort(z)
109: 
110: # Create figure ...
111: # NOTE: If "transform" is not subsequently supplied then it is assumed to be
112: #       "cartopy.crs.OSGB()" as that is what the axes are.
113: fg = matplotlib.pyplot.figure(figsize = (8, 12), dpi = 300)
114: ax = matplotlib.pyplot.axes(projection = cartopy.crs.OSGB())
115: 
116: # Add background image ...
117: ax.imshow(
118:     matplotlib.pyplot.imread(f'OrdnanceSurveyBackgroundImages/{meta["MiniScale_(mono)_R22"]["greyscale"]}'),
119:     cmap = "gray",
120:     extent = meta["MiniScale_(mono)_R22"]["extent"],
121:     interpolation = "bicubic",
122:     origin = "upper",
123:     vmin = 0.0,
124:     vmax = 1.0
125: )
126: 
127: # Plot data (layering them correctly) and add colour bar ...
128: sc = ax.scatter(
129:     x[k],
130:     y[k],
131:     s = 10.0,
132:     c = z[k],
133:     linewidth = 0.1,
134:     edgecolors = "black",
135:     cmap = matplotlib.pyplot.cm.rainbow,
136:     vmin = 900.0,
137:     transform = cartopy.crs.PlateCarree()
138: )
139: cb = fg.colorbar(sc)
140: 
141: # Configure axes ...
142: ax.set_title("E900 Mountains In The British Isles")
143: 
144: # Configure color bar ...
145: cb.set_label("Elevation [m]")
146: 
147: # Save figure ...
148: fg.savefig("british-hills-E900.png", bbox_inches = "tight", dpi = 300, pad_inches = 0.1)
149: matplotlib.pyplot.close(fg)
150: pyguymer3.image.optimize_image("british-hills-E900.png", strip = True)
151: 
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(
088:                     "\"{:s}\" is {:,.1f}m ASL with a prominence of {:,.1f}m at ({:f}°,{:f}°).\n".format(
089:                         row["Name"],
090:                         float(row["Metres"]),
091:                         float(row["Drop"]),
092:                         float(row["Latitude"]),
093:                         float(row["Longitude"])
094:                     )
095:                 )
096: 
097: # Print summary ...
098: print(f"There are {n:,d} P600 mountains in The British Isles.")
099: 
100: # ******************************************************************************
101: 
102: # Load tile metadata ...
103: meta = json.load(open("OrdnanceSurveyBackgroundImages/miniscale.json", "rt", encoding = "utf-8"))
104: 
105: # Convert lists to arrays and find the sorted keys ...
106: x = numpy.array(x)                                                              # [°]
107: y = numpy.array(y)                                                              # [°]
108: z = numpy.array(z)                                                              # [m]
109: k = numpy.argsort(z)
110: 
111: # Create figure ...
112: # NOTE: If "transform" is not subsequently supplied then it is assumed to be
113: #       "cartopy.crs.OSGB()" as that is what the axes are.
114: fg = matplotlib.pyplot.figure(figsize = (8, 12), dpi = 300)
115: ax = matplotlib.pyplot.axes(projection = cartopy.crs.OSGB())
116: 
117: # Add background image ...
118: ax.imshow(
119:     matplotlib.pyplot.imread(f'OrdnanceSurveyBackgroundImages/{meta["MiniScale_(mono)_R22"]["greyscale"]}'),
120:     cmap = "gray",
121:     extent = meta["MiniScale_(mono)_R22"]["extent"],
122:     interpolation = "bicubic",
123:     origin = "upper",
124:     vmin = 0.0,
125:     vmax = 1.0
126: )
127: 
128: # Plot data (layering them correctly) and add colour bar ...
129: sc = ax.scatter(
130:     x[k],
131:     y[k],
132:     s = 10.0,
133:     c = z[k],
134:     linewidth = 0.1,
135:     edgecolors = "black",
136:     cmap = matplotlib.pyplot.cm.rainbow,
137:     vmin = 600.0,
138:     transform = cartopy.crs.PlateCarree()
139: )
140: cb = fg.colorbar(sc)
141: 
142: # Configure axes ...
143: ax.set_title("P600 Mountains In The British Isles")
144: 
145: # Configure color bar ...
146: cb.set_label("Prominence [m]")
147: 
148: # Save figure ...
149: fg.savefig("british-hills-P600.png", bbox_inches = "tight", dpi = 300, pad_inches = 0.1)
150: matplotlib.pyplot.close(fg)
151: pyguymer3.image.optimize_image("british-hills-P600.png", strip = True)
152: 
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(
087:                     "\"{:s}\" is {:,.1f}m ASL with a prominence of {:,.1f}m at ({:f}°,{:f}°).\n".format(
088:                         row["Name"],
089:                         float(row["Metres"]),
090:                         float(row["Drop"]),
091:                         float(row["Latitude"]),
092:                         float(row["Longitude"])
093:                     )
094:                 )
095: 
096: # Print summary ...
097: print(f"There are {n:,d} P900 mountains in The British Isles.")
098: 
099: # ******************************************************************************
100: 
101: # Load tile metadata ...
102: meta = json.load(open("OrdnanceSurveyBackgroundImages/miniscale.json", "rt", encoding = "utf-8"))
103: 
104: # Convert lists to arrays and find the sorted keys ...
105: x = numpy.array(x)                                                              # [°]
106: y = numpy.array(y)                                                              # [°]
107: z = numpy.array(z)                                                              # [m]
108: k = numpy.argsort(z)
109: 
110: # Create figure ...
111: # NOTE: If "transform" is not subsequently supplied then it is assumed to be
112: #       "cartopy.crs.OSGB()" as that is what the axes are.
113: fg = matplotlib.pyplot.figure(figsize = (8, 12), dpi = 300)
114: ax = matplotlib.pyplot.axes(projection = cartopy.crs.OSGB())
115: 
116: # Add background image ...
117: ax.imshow(
118:     matplotlib.pyplot.imread(f'OrdnanceSurveyBackgroundImages/{meta["MiniScale_(mono)_R22"]["greyscale"]}'),
119:     cmap = "gray",
120:     extent = meta["MiniScale_(mono)_R22"]["extent"],
121:     interpolation = "bicubic",
122:     origin = "upper",
123:     vmin = 0.0,
124:     vmax = 1.0
125: )
126: 
127: # Plot data (layering them correctly) and add colour bar ...
128: sc = ax.scatter(
129:     x[k],
130:     y[k],
131:     s = 10.0,
132:     c = z[k],
133:     linewidth = 0.1,
134:     edgecolors = "black",
135:     cmap = matplotlib.pyplot.cm.rainbow,
136:     vmin = 900.0,
137:     transform = cartopy.crs.PlateCarree()
138: )
139: cb = fg.colorbar(sc)
140: 
141: # Configure axes ...
142: ax.set_title("P900 Mountains In The British Isles")
143: 
144: # Configure color bar ...
145: cb.set_label("Prominence [m]")
146: 
147: # Save figure ...
148: fg.savefig("british-hills-P900.png", bbox_inches = "tight", dpi = 300, pad_inches = 0.1)
149: matplotlib.pyplot.close(fg)
150: pyguymer3.image.optimize_image("british-hills-P900.png", strip = True)
151: 
You may also download “british-hills-P900.py” directly or view “british-hills-P900.py” on GitHub Gist.