from colorspace import qualitative_hcl, dataset
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
# Loading HarzTraffic data set
= dataset("HarzTraffic")
df
# Palette (modified "Dark 3" sequential palette)
= qualitative_hcl("Dark 3", h1 = -150, h2 = 120)
pal
# Creating plot
= plt.subplots(1, 1, figsize = (8, 4))
fig, ax = df, x = "temp", y = "bikes",
sns.scatterplot(data ="season", ax = ax,
hue= pal.colors(4))
palette "Number of bikes given daily mean temperature")
plt.title("temperature [deg C]")
plt.xlabel( plt.show()
HCL-Based Color Scales for seaborn
This article shows a series of different plots and figures using the seaborn
graphics library using color maps based on the colorspace package.
Scatterplot
The following example shows the number of motorbikes recorded by an automatic traffic counting station in the Harz Mountains (Germany), an region very popular with bikers. The number of bikes (y-axis) is plotted against the daily mean temperature (x-axis) and colored by season using custom colors from a modified version of the HCL-based qualitative color palette “Dark 3”.
Multi-group histogram
The next example shows a multi-group distribution plot (kind = "kde"
) based on the ‘HarzTraffic’ data set where the distribution of the daily maximum temperature is shown given the prevailing season. The colors are based on a modified sequential HCL-based palette using “Dark 3” as template (adjusting hues).
from colorspace import qualitative_hcl, dataset
from matplotlib import pyplot as plt
import seaborn as sns
# Loading penguins data set
= dataset("HarzTraffic")
df
# Palette to be used
= qualitative_hcl("Dark 3", h1 = -180, h2 = 100)
pal
# Creating plot
= sns.displot(data = df, x = "tempmax", hue = "season", fill = "season",
g = "kde", rug = True, height = 4, aspect = 1.5,
kind = pal.colors(4))
palette "temperature [deg C]")
g.set_axis_labels(set(title = "Distribution of daily maximum temperature given season")
g.
plt.tight_layout() plt.show()
Heatmap
HCL-based color maps (LinearSegmentedColormap
objects) can be used directly for seaborn heatmaps. The plot below shows the joint density of the daily maximum temperature (y-axis) and daily minimum temperature (x-axis) based on the ‘HarzTraffic’ data set.
The left subplot employs one of the pre-defined sequential HCL-based color palette “YlOrRd” (yellow-orange-red) in reverse order, while the right subplot shows the same information but using a custom sequential HCL-based palette. Instead of reversing the palette via rev = True
, the .reversed()
method on the LinearSegmentedColormap
(cmap) is used to get the same effect.
from colorspace import sequential_hcl, dataset
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
# Loading penguins data set
= dataset("HarzTraffic")
df
# New figure with 2 subplots
= plt.subplots(1, 2, figsize = (12, 6))
fig, (ax1, ax2)
# Draw heatmap (left)
= sns.histplot(x = "tempmin", y = "tempmax", data = df,
g1 = 25, pthresh = .1, ax = ax1,
bins = sequential_hcl("YlOrRd", rev = True).cmap())
cmap
-50, 50], [-50, 50], color = "black") # Adding diagonal
g1.plot([set(xlim = [-8, 18], ylim = [-5, 32]) # Re-adjusting limits
g1."daily minimum temperature [deg C]")
g1.set_xlabel("daily maximum temperature [deg C]")
g1.set_ylabel("Joint density of daily minimum and maximum\n" +
g1.set_title("temperature. Sonnenberg, Harz, Germany")
# Create fully customized HCL-based sequential palette
= sequential_hcl(h = [330, 170], c = [45, 70, 10],
custom_cmap = [25, 95], power = [0.5, 1.5]).cmap().reversed()
l
# Draw heatmap (right) with customized color map
= sns.histplot(x = "tempmin", y = "tempmax", data = df,
g2 = 25, pthresh = .1, ax = ax2,
bins = custom_cmap)
cmap
-50, 50], [-50, 50], color = "black") # Adding diagonal
g2.plot([set(xlim = [-8, 18], ylim = [-5, 32]) # Re-adjusting limits
g2."daily minimum temperature [deg C]")
g2.set_xlabel("daily maximum temperature [deg C]")
g2.set_ylabel("Joint density of daily minimum and maximum\n" +
g2.set_title("temperature. Sonnenberg, Harz, Germany")
plt.show()
Lineplot with multiple facets
This example shows the number of bikes and cars for the different years by day of year (yday
; Julian day) using a diverging HCL-based color palette.
from colorspace import diverging_hcl
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
# Loading penguins data set
= dataset("HarzTraffic")
df "year"] = pd.DatetimeIndex(df.date).year
df[
# Reorganizing the data
= df.loc[:, ["year", "yday", "bikes"]].rename(columns = {"bikes": "count"})
a 2, "type", "bikes")
a.insert(= df.loc[:, ["year", "yday", "cars"]].rename(columns = {"cars": "count"})
b 2, "type", "cars")
b.insert(
# Concatenate (rowwise)
= pd.concat([a, b], axis = 0)
df del a, b
# Number of colors required
= len(np.unique(df.year))
N
# Plot the lines on two facets
= df, x = "yday", y = "count",
sns.relplot(data = "year", row = "type",
hue = "line", size_order = ["cars", "bikes"],
kind = 4, aspect = 3, facet_kws = dict(sharey = False),
height = diverging_hcl("Green-Orange").colors(N))
palette plt.show()
Barplot
The Harz region in Germany is well known amongst bikers which often use their time on the weekend to go for a ride. To visualize this, the following barplot shows the average number of bikes (with error bars) during the summer seasons (June-August) 2021-2023 based on the “HarzTraffic” data set. The qualitative HCL-based color palette “Harmonic” is used to colorize the different days of week.
from colorspace import qualitative_hcl, dataset
import matplotlib.pyplot as plt
import seaborn as sns
# Loading data set
= dataset("HarzTraffic")
df = df.loc[(df.season == "summer"), :]
df
= "dayofweek", y = "bikes", hue = "dow", data = df,
sns.barplot(x = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
order = False,
legend = qualitative_hcl("Harmonic").colors(7))
palette "Average number of bikes per day of week\nsummer season 2021-2023")
plt.title( plt.show()
As a slightly more complex example, the visualization below shows grouped barplots with the total number of bikes, cars, trucks, and other vehicles registered on a monthly basis between January 2021 and November 2023, using the example data set The different vehicle types are colorized using the sequential HCL-based color palette “Plasma”. The upper plot shows original colors (no visual constraints), the lower simulates the same colors seen by people with deuteranope vision (green-yellow-red weakness).
from colorspace import sequential_hcl, dataset, deutan
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# Loading penguins data set
= dataset("MonthlyHarzTraffic")
df
# Reshaping the pandas DataFrame
= []
res for t in ["bikes", "cars", "trucks", "others"]:
= df.loc[:, ["year", "month", t]].rename(columns = {t: "count"})
tmp 3, "type", t)
tmp.insert(
res.append(tmp)= pd.concat(res, axis = 0)
df del res, tmp
# New figure
= plt.subplots(2, 1)#, figsize = (8, 6))
fig, (ax1, ax2)
# Plotting (unconstraint and deuteranope vision)
= "month", y = "count", hue = "type", data = df, ax = ax1,
sns.barplot(x = sequential_hcl("Plasma")(4))
palette = "month", y = "count", hue = "type", data = df, ax = ax2,
sns.barplot(x = deutan(sequential_hcl("Plasma")(4)))
palette
# Setting title, adjusting legend
"Total number of vehicles, 2021-2023")
ax1.set_title(None)
ax1.set_xlabel("upper left", ncol = 4, title = None, frameon = False)
sns.move_legend(ax1, "upper left", ncol = 4, title = None, frameon = False)
sns.move_legend(ax2, plt.show()