Python matplotlib example sunshine duration colored by temperature#

Software requirements:

  • Python 3

  • numpy

  • pandas

  • matplotlib

Run the sunshine duration data colored by temperature example script:

python sunshine_duration_data_colored_by_temperature.py

Script sunshine_duration_data_colored_by_temperature.py:

#!/usr/bin/env python
# coding: utf-8

# DKRZ example
#
# Color bars by another variable
#
# Yearly averages for Germany (DWD):
#
# - Sunshine duration [h]
# - Temperature [°C]
#
# Average reference sunshine suration per year 1961-1990: 1544 hours
#
# Content
# - read the CSV data
# - create new DataFrame
# - compute the average temperature for a 30-years reference
# - compute the linear regression of the temperature
# - create the bar plot
# - color the bars for the yearly sunshine duration data by temperature data
#
# 2023 copyright DKRZ, kmf
#
import os
import pandas as pd
import numpy as np

import matplotlib.pyplot as plt
from matplotlib.cm import ScalarMappable
import matplotlib.colors as mcolors

# Read the CSV data
#
# Sunshine duration
file_sun = os.environ['HOME']+'/data/DWD/annual_sunshine_duration_regional_averages_sd_year.txt'
file_temp = os.environ['HOME']+'/data/DWD/annual_air_temperature_mean_regional_averages_tm_year.txt'

df_sun = pd.read_csv(file_sun, skiprows=[0], sep=';', usecols=['#Jahr','Deutschland'])

# Get the number of years of the sunshine duration dataset.
nyears = df_sun.shape[0]

# Temperature
df_temp = pd.read_csv(file_temp, skiprows=[0], sep=';', usecols=['#Jahr','Deutschland'])

# Since the temperature dataset contains more timesteps we have to select the same times as for the sunshine data. Furthermore, we have to reset the index of the selected data frame to 0.
df_temp2 = df_temp.loc[df_temp['#Jahr'] >= 1951]
df_temp2.reset_index(inplace=True)

# Temperature min and max
print(str(df_temp2['Deutschland'].min()) + ' - ' + str(df_temp2['Deutschland'].max()))

# Reference average temperature
#
# Compute the average temperature for a 30-years reference time (1961-1990).
refdata = round(df_sun['Deutschland'].loc[(df_sun['#Jahr'] >= 1961) & (df_sun['#Jahr'] <= 1990)])
sun_avg = round(np.sum(refdata)/30)

# Create new DataFrame
#
# Merge the data of the sunshine duration and temperature into a new DataFrame.
data = [[df_sun['#Jahr'][i], df_sun['Deutschland'][i], df_temp2['Deutschland'][i]] for i in range(0,nyears)]

df = pd.DataFrame(data, columns=['Jahr','Sunshine','Temperature'])

# Linear regression
#
# Compute the linear regression of the sunshine duration data:
#
# ```python
# sun_trend = np.polynomial.Polynomial.fit(df.Jahr, df.Sunshine, deg=1)
# sun_trend = sun_trend.convert()
# ```
#
# or
#
# ```python
# coef = np.polyfit(df.Jahr, df.Sunshine, deg=1)
# sun_trend = np.poly1d(coef)
# ```
coef = np.polyfit(df.Jahr, df.Sunshine, deg=1)
sun_trend = np.poly1d(coef)

# Create the plot

fig, ax = plt.subplots(figsize=(16,8))

ax.set_title('Sunshine duration colored by temperature\n1951-2017',
              fontsize=16,
              fontweight='bold',
              y=1.05)

colormap = 'YlOrBr' #'RdYlBu_r'
cmap = plt.cm.get_cmap(colormap)
cmap_short = mcolors.LinearSegmentedColormap.from_list(
                     'trunc({n},{a:.2f},{b:.2f})'.format(n=cmap.name, a=0.2, b=0.8),
                      cmap(np.linspace(0.2, 0.8, 10)))
sun_min = 7.5
sun_max = 10.5
c = [(x-sun_min) / (sun_max-sun_min) for x in df.Temperature]
colors = cmap_short(c)

ax.set_xlim([df['Jahr'][0]-1, df['Jahr'][nyears-1]+1])
ax.set_ylim([1300, 2020])

plot = ax.bar(df.Jahr,
              df.Sunshine,
              color=colors,
              edgecolor='black',
              linewidth=0.5)

sm = ScalarMappable(cmap=cmap, norm=plt.Normalize(sun_min,sun_max))
sm.set_array([])

cbar = plt.colorbar(sm, shrink=0.7)
cbar.set_label('Temperature [°C]', rotation=270, labelpad=25)

ax.plot(df.Jahr, sun_trend(df.Jahr),
        linestyle=(5, (10, 3)),
        linewidth=1.5,
        color='black',
        label='sunshine duration trend')

ax.plot([df.Jahr[0],df.Jahr[nyears-1]], [sun_avg,sun_avg],
        linestyle=(5, (10, 3)),
        linewidth=1.5,
        color='silver',
        label='average sunshine duration (1961-1990)')

plt.legend()

plt.savefig('plot_sunshine_duration_colored_by_temperature.png',
             bbox_inches='tight',
             facecolor='white')

Plot result:

image0