Reputation: 49
I am trying to plot data (.csv) per municipality (.shp) on a map from Scandinavia using contourf. This data has a big range in values (see list all the way at the bottom), for which I use a log-scale to also show the level of detail in the lower values. The code I use worked fine until recently. See image below on the left.
However, when I run the exact same code now, the maps show too light colouring, which does not match either the values of the data or the colourbar (see image below on the right). I assume this has something to do with a version update, but I cannot figure out how to fix it to show the data with the right colours in the map.
If there is an easier way to display the values on a logarithmic scale I am also all ears!
This is my code:
import cartopy.crs as ccrs
import numpy as np
from shapely.geometry import Polygon
import cartopy
from cartopy.io import shapereader
import matplotlib
import pandas
import geopandas
import cartopy.io.img_tiles as cimgt
import matplotlib.pyplot as plt
import cartopy.feature as feature
import shapely
projection = ccrs.Mercator()
transform = ccrs.PlateCarree()
extent = [4.5, 31.9, 54.7, 71.24]
cmap = matplotlib.cm.get_cmap('Reds')
# Get borders
resolution = '10m'
category = 'cultural'
name = 'admin_0_countries'
shpfilename = shapereader.natural_earth(resolution, category, name)
shpfilenamemunicipalities = '/path/to/ScandinaviaKommuner.shp'
# Read the shapefile using geopandas
df = geopandas.read_file(shpfilename)
df2 = geopandas.read_file(shpfilenamemunicipalities)
# Select the countries of interest
scan3 = df[ df['ADMIN'].isin(['Norway', 'Finland', 'Sweden']) ]
scan3_dissolved = scan3.dissolve(by='LEVEL')
poly = [scan3_dissolved['geometry'].values[0]]
# Create the mask
stamen_terrain = cimgt.Stamen('terrain_background')
st_proj = stamen_terrain.crs #projection used by Stamen images
ll_proj = ccrs.PlateCarree()
def rect_from_bound(xmin, xmax, ymin, ymax):
"""Returns list of (x,y)'s for a rectangle"""
xs = [xmax, xmin, xmin, xmax, xmax]
ys = [ymax, ymax, ymin, ymin, ymax]
return [(x, y) for x, y in zip(xs, ys)]
pad1 = .1 #padding, degrees unit
exts = [poly[0].bounds[0] - pad1, poly[0].bounds[2] + pad1, poly[0].bounds[1] - pad1, poly[0].bounds[3] + pad1];
msk = Polygon(rect_from_bound(*exts)).difference(poly[0].simplify(0.01))
msk_stm = st_proj.project_geometry(msk, ll_proj) # project geometry to the projection used by stamen
# Load the .csv data
firedata = pandas.read_csv('/path/to/countrylevel_firedata.csv', delimiter=';', decimal='.')
firedatamunicipalities = pandas.read_csv('/path/to/municipalitylevel_firedata.csv', delimiter=';', decimal='.')
# Subset .csv data
countries = firedata['Country'].tolist()
municipalities = firedatamunicipalities['Municipality'].tolist()
fireextents = firedatamunicipalities['FireIntensity'].tolist()
# Normalise the fire data to between 0 and 1 to extract the colour and log transform
fireextents_log = list(range(0,966))
for fireextent, log in zip(fireextents, fireextents_log):
if fireextent>0:
fireextents_log[log] = np.log(fireextent)
else:
fireextents_log[log] = np.nan
fireextents_norm = (fireextents_log-np.nanmin(fireextents_log))/(np.nanmax(fireextents_log) - np.nanmin(fireextents_log))
# Create a plot
fig, axs = plt.subplots(nrows = 1, ncols = 1,
subplot_kw = {'projection': projection},
layout='constrained')
axs.set_extent(extent)
axs.add_feature(feature.BORDERS, linewidth=2.5, zorder=15)
axs.set_extent(extent)
axs.axis('off')
axs.add_geometries(shapely.get_parts(poly[0]), crs=transform, facecolor='none',
edgecolor='black', linewidth=2.5, zorder=18)
axs.add_geometries(msk_stm, st_proj, facecolor='#f3f8ff', edgecolor='none',
zorder=16)
for municipality, fireextent_norm in zip(municipalities, fireextents_norm):
poly3 = df2.loc[df2['Municipali'] == municipality]['geometry'].values
if fireextent_norm > 0:
rgba2 = cmap(fireextent_norm)
else:
rgba2 = 'white'
axs.add_geometries(poly3, crs=transform, facecolor=rgba2, edgecolor='black', linewidth=1, zorder=14)
dummy_scat = axs.scatter(fireextents, fireextents, c=fireextents, cmap=cmap, zorder=0,
norm=matplotlib.colors.LogNorm())
cbar = fig.colorbar(dummy_scat, ax=axs, orientation='horizontal', shrink=1, pad=0.01)
cbar.set_label('Fire intensity (ha burnt forest/fire) \nover the period 2008-2024', size=65, labelpad=15)
cbar.ax.tick_params(labelsize=60)
plt.show()
A part of the fire extents data to show the big range in values below. As can be seen, the values do reach the 10³ range, and should be displayed as such:
print(fireextents)
>>> [4183.6667, 1378.0, 1065.0, 991.6, 908.0, 612.0, 548.0625, 520.0, 412.7778, 331.0, 324.0, 280.5, 259.3333, 259.0, 234.0, 222.0, 212.6667, 199.0, 169.0, 158.3333, 153.5, 148.6, 147.5, 145.0, 133.8, 130.0, 108.3333, 105.25, 103.0, 103.0, 90.0, 86.0, 84.3, 82.1667, 80.6, 80.0, 79.8571, 75.0, 74.0, 71.0, 65.3, 63.0, 59.6, 58.0, 58.0, 57.6667, 55.0, 55.0, 54.9, 54.8636, 53.25, 51.0, 50.4667, 49.0, 49.0, 49.0, 48.7143, 48.0, 47.1071, 47.0, 46.5, 46.0, 45.0, 43.0, 42.2, 42.0, 41.0, 40.0, 38.2, 35.4, 34.9, 34.9, 34.5, 34.0, 34.0, 34.0, 33.8, 33.0, 33.0, 33.0, 32.8, 32.0, 31.0, 30.3333, 30.0, 30.0, 30.0, 29.6667, 29.5, 29.4, 29.3, 29.2857, 28.1667, 28.0, 28.0, 28.0, 27.0, 27.0, 26.0, 26.0, 26.0, 26.0, 26.0, 26.0, 25.8, 25.0, 25.0, 25.0, 25.0, 24.6, 24.5, 24.0, 24.0, 23.5, 23.1429, 23.0, 23.0, 22.0, 21.3, 19.0, 19.0, 19.0, 19.0, 19.0, 18.0, 17.5, 17.0, 16.5, 15.9167, 15.8, 15.5, 15.5, 15.3, 15.0714, 15.0, 15.0, 15.0, 14.5, 14.0, 13.5, 13.3333, 13.0, 12.5, 12.5, 12.2941, 12.0588, 12.0, 12.0, 12.0, 11.6, 11.0, 10.6667, 10.0, 9.6667, 9.6667, 9.5, 9.5, 9.0, 8.5714, 8.5, 8.3, 7.1667, 7.0, 7.0, 7.0, 6.6, 6.0, 6.0, 6.0, 6.0, 5.5, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 4.5, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 3.75, 3.5, 3.5, 3.4, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 2.5, 2.2, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 1.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... 0.0, 0.0, 0.0]
Upvotes: 0
Views: 79