I've got this code that is supposed to make a heatmap, but with circles instead of squares/rectangles, so far testing it with placeholder colors, looks like this:
import matplotlib.pyplot as plt
import matplotlib.colors as mcl
import numpy as np
import pandas as pd
from typing import List, T
from random import uniform
def l_flatten(l: List[T]) -> List[T]:
return [j for i in l for j in i]
def get_luminance(color: str) -> float:
# taken from Seaborn's utils
rgb = mcl.colorConverter.to_rgba_array(color)[:, :3]
rgb = np.where(rgb <= .03928, rgb / 12.92, ((rgb .055) / 1.055) ** 2.4)
lum = rgb.dot([.2126, .7152, .0722])
try:
lum = lum.item()
except ValueError:
pass
return lum
class CircleHeatmap:
def __init__(self,
ax: plt.Axes,
df: pd.DataFrame,
colors: List[str],
annot_show: bool,
annot_size: float,
circle_size: float,
x_labels: List[str],
x_labels_size: float,
x_labels_color: str,
y_labels: List[str],
y_labels_size: float,
y_labels_color: str) -> None:
# pass user-provided variables
self.ax = ax
self.df = df
self.colors = colors
self.annot_show = annot_show
self.annot_size = annot_size
self.circle_size = circle_size
self.x_labels = x_labels
self.x_labels_size = x_labels_size
self.x_labels_color = x_labels_color
self.y_labels = y_labels
self.y_labels_size = y_labels_size
self.y_labels_color = y_labels_color
# pass technical variables
self.y_size, self.x_size = self.df.shape
self.x_arr, self.y_arr = np.meshgrid(np.arange(self.x_size),
np.arange(self.y_size))
self.x_arr, self.y_arr = ((self.x_arr 0.5).flat,
(self.y_arr 0.5).flat)
self.x_len, self.y_len = [np.linspace(0, len(i), len(i) 1)[:-1] 0.5
for i in (self.x_labels, self.y_labels)]
self.df_values = l_flatten(self.df.values.tolist())
def plot(self) -> None:
self.ax.scatter(self.x_arr, self.y_arr,
s = self.circle_size ** 2,
c = self.colors)
def labels(self) -> None:
self.ax.set_xticks(self.x_len)
self.ax.set_yticks(self.y_len)
self.ax.set_xticklabels(self.x_labels, fontsize = self.x_labels_size,
color = self.x_labels_color)
self.ax.set_yticklabels(self.y_labels, fontsize = self.y_labels_size,
color = self.y_labels_color)
def main() -> None:
fig, ax = plt.subplots(figsize = (20, 30))
df = pd.DataFrame([[uniform(0, 1) for j in range(20)] for i in range(30)])
colors = ["#EC4E20", "#FF9505", "#016FB9"] * 200
heatmap = CircleHeatmap(ax = ax,
df = df,
colors = colors,
annot_show = False,
annot_size = 16,
circle_size = 45,
x_labels = [i for i in range(20)],
x_labels_size = 20,
x_labels_color = "black",
y_labels = [i for i in range(30)],
y_labels_size = 20,
y_labels_color = "black")
heatmap.plot()
heatmap.labels()
for i in ["top", "bottom", "right", "left"]:
ax.spines[i].set_visible(False)
plt.savefig("test2.png")
if __name__ == "__main__":
main()