import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import pandas_datareader as pdr
from datetime import datetime
from matplotlib.colors import LinearSegmentedColormap
= ["#3B9AB2", "#78B7C5", "#EBCC2A", "#E1AF00", "#F21A00"]
main_colors = LinearSegmentedColormap.from_list("custom_colormap", main_colors)
colormap
= pdr.DataReader(
industries_ff_daily_raw ="12_Industry_Portfolios_daily",
name="famafrench",
data_source="1927-01-01",
start="2022-12-31")[0]
end
= (industries_ff_daily_raw
industries_ff_daily 100)
.divide(="date")
.reset_index(names=lambda x: pd.to_datetime(x["date"].astype(str)))
.assign(datestr.lower, axis="columns")
.rename(
)
= (industries_ff_daily
industries_long ="date", var_name="name", value_name="value")
.melt(id_vars
)
= sorted(industries_long["name"].unique())
industries_order
= (industries_long
data_plot =industries_long["date"].dt.to_period("Y"))
.assign(year"year", "name"])
.groupby([=("value", "mean"),
.aggregate(total=("value", "std"))
vola
.reset_index()
.assign(=lambda x: pd.qcut(x["vola"], 42, labels=False)
vola_ntile
)
)
= 300
dpi = 2400/dpi
width = 1800/dpi
height = 4
num_cols = int(len(industries_order)/num_cols)
num_rows = plt.subplots(
fig, axs
num_rows, num_cols,=True,
constrained_layout={"projection": "polar"},
subplot_kw=(width, height),
figsize=dpi
dpi
)= axs.flatten()
axs
for i in enumerate(industries_order):
= data_plot.copy().query(f'name == "{i[1]}"')
df = df["total"].min()
min_value = df["total"].max()
max_value = df["total"].std()
std_value "total"] = 2*(df["total"]-min_value)/(max_value-min_value)-1
df[
= np.linspace(0, 2*np.pi, len(df), endpoint=False)
angles = df["total"].values
values = 2*np.pi/len(values)
width = np.pi/2
offset
= axs[i[0]]
ax
ax.set_theta_offset(offset)-std_value*1400, 1)
ax.set_ylim(False)
ax.set_frame_on(False)
ax.xaxis.grid(False)
ax.yaxis.grid(
ax.set_xticks([])
ax.set_yticks([])
= df["vola_ntile"].values
color_values = plt.Normalize(min(color_values), max(color_values))
normalize = colormap(normalize(color_values))
colors
ax.bar(
angles, values,=width, color=colors, edgecolor="white", linewidth=0.2
width
)
plt.tight_layout()=-0.2, hspace=-0.1)
plt.subplots_adjust(wspace
plt.gcf().savefig("images/cover-image.png", dpi = 300, pad_inches=0, transparent=False
)
Cover Image
The cover of the book is inspired by the fast growing generative art community in R. Generative art refers to art that in whole or in part has been created with the use of an autonomous system. Instead of creating random dynamics, we rely on what is core to the book: The evolution of financial markets. Each circle corresponds to one of the twelve Fama-French industry portfolios, whereas each bar represents the average annual return between 1927 and 2022. The bar color is determined by the standard deviation of returns for each industry. The few lines of code below replicate the entire figure.