Skip to content

Instantly share code, notes, and snippets.

@jflopezfernandez
Created September 7, 2023 06:18
Show Gist options
  • Save jflopezfernandez/bca170d837d51f9ae5811d81e5a76ee3 to your computer and use it in GitHub Desktop.
Save jflopezfernandez/bca170d837d51f9ae5811d81e5a76ee3 to your computer and use it in GitHub Desktop.
"""Overview of Plotting in Python Using Matplotlib and Seaborn.
python3 -m pip install --upgrade pip wheel setuptools packaging
python3 -m pip install --upgrade numpy scipy matplotlib seaborn
This script also needs FFMPEG on Windows to be able to render animations
as MP4 files (maybe on Linux too, I don't know).
"""
from collections import Counter
from typing import Any, Callable, List
import locale
from venv import create
from absl import flags
from absl import logging
from matplotlib.animation import FuncAnimation
from numpy.random import default_rng
from seaborn import FacetGrid
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import scipy as sc
import seaborn as sns
# Initialize the current locale.
locale.setlocale(locale.LC_ALL, '')
# Configure Seaborn visualization library.
sns.set_theme(style="darkgrid")
rng = default_rng()
def create_penguin_bill_length_vs_depth_plot() -> FacetGrid:
dataset = sns.load_dataset("penguins")
plot = sns.relplot(data=dataset, x="bill_length_mm", y="bill_depth_mm", hue="body_mass_g", palette="crest")
plot.set_axis_labels("Bill Length (mm)", "Bill Depth (mm)", labelpad=10)
plot.legend.set_title("Body Mass (g)")
plot.figure.set_size_inches(8.5, 5.0)
plot.ax.set_title("Analysis of Penguin Bill Depth As a Function of Length")
plot.ax.set_xmargin(0.15)
plot.ax.set_ymargin(0.25)
plot.tight_layout()
return plot
def create_flipper_length_histograms() -> FacetGrid:
dataset = sns.load_dataset("penguins")
plot = sns.displot(dataset, x="flipper_length_mm", col="species", row="sex", binwidth=3, height=3, facet_kws=dict(margin_titles=True))
plot.set_axis_labels("Flipper Length (mm)", "Number of Penguins", labelpad=10)
plot.figure.set_size_inches(8.5, 5.0)
# These three attempts at setting the overall title were massively
# unsuccessful and are kept here only to be able to easily reference what NOT
# to do.
# plot.ax.set_title("Distribution of Penguin Flipper Length by Sex and Species")
# plot.figure.set_label("This is an example label.")
# plot.axes[0][0].set_title("Distribution of Penguin Flipper Length by Sex and Species")
plot.figure.suptitle("Distribution of Penguin Flipper Length by Sex and Species")
plot.tight_layout()
return plot
def create_smoker_tips_boxplots() -> FacetGrid:
dataset = sns.load_dataset("tips")
# plot = sns.boxplot(dataset, x="day", y="tip", hue="smoker")
# sns.despine(offset=10, trim=True)
# plot.set_xlabel("Day of the Week")
# plot.set_ylabel("Tip (USD)")
plot = sns.relplot(dataset, x="total_bill", y="tip", hue="sex")
plot.set_axis_labels("Total Bill (USD)", "Tip (USD)", labelpad=10)
plot.legend.set_title("Sex")
plot.ax.set_title("Tipping Behavior as a Function of Total Bill")
plot.ax.xaxis.set_major_formatter(lambda x, _: f'${x:.02f}')
plot.ax.yaxis.set_major_formatter(lambda y, _: f'${y:.02f}')
plot.figure.set_size_inches(8.5, 5.0)
plot.ax.set_xmargin(0.15)
plot.ax.set_ymargin(0.25)
plot.figure.tight_layout()
return plot
def create_plots() -> None:
plot_functions = {
create_penguin_bill_length_vs_depth_plot: False,
create_flipper_length_histograms: False,
create_smoker_tips_boxplots: True,
}
for plot_function, enabled in plot_functions.items():
if enabled:
# The return value of each of these calls is the plot that was created.
# Every one of these returned plots is a `FacetGrid` instance.
_ = plot_function()
plt.show()
def create_animation() -> None:
class UpdateFrame:
def __init__(self, axes, /, seed = 42) -> None:
self.seed = seed
self.rng = default_rng(self.seed)
self.color = "tab:blue"
self.iq_scores = []
self.iq_scores_counter = Counter()
self.max_iq = 0
self.y_max = 1
# logging.error('y-max: %d', self.y_max)
self.axes = axes
self.figure, b, c = self.axes.hist(self.iq_scores, bins=40, density=False, align="mid", color=self.color, label="Overall IQ Scores")
self.b = b
self.c = c
self.axes.set_xlim(50, 150)
self.axes.set_ylim(0, self.y_max)
self.axes.grid(True)
self.axes.axvline(x=0, color="black", linewidth=2.5)
self.axes.axhline(y=0, color="black", linewidth=2.5)
def __call__(self, i):
if i == 0:
# self.figure.set_data([])
return self.figure, self.b, self.c
# iq_score = int(self.rng.normal(100, 15))
# self.iq_scores.append(iq_score)
self.iq_scores += [int(x) for x in self.rng.normal(100, 15, size=5).tolist()]
# logging.error(self.iq_scores)
# self.iq_scores_counter[iq_score] += 1
self.iq_scores_counter = Counter(self.iq_scores)
_, self.max_iq = self.iq_scores_counter.most_common()[0]
self.max_iq *= 3
# logging.error('Max IQ: %d', self.max_iq)
if self.y_max <= self.max_iq:
self.y_max = self.max_iq + 1
# self.y_max = 1 + int(self.max_iq * 1.015)
# logging.error('y-max: %d', self.y_max)
# self.figure.set_data(self.iq_scores)
self.axes.clear()
self.figure, b, c = self.axes.hist(self.iq_scores, bins=40, density=False, align="mid", color=self.color, label="Overall IQ Scores")
self.b = b
self.c = c
self.axes.set_xlim(50, 150)
self.axes.set_ylim(0, self.y_max)
self.axes.grid(True)
self.axes.axvline(x=0, color="black", linewidth=2.5)
self.axes.axhline(y=0, color="black", linewidth=2.5)
return self.figure, self.b, self.c
seed = 42
figure, axes = plt.subplots()
frame_updater = UpdateFrame(axes, seed=seed)
animation = FuncAnimation(figure, frame_updater, frames=250, interval=150, blit=False)
# animation.save("function-animation.mp4", fps=1)
plt.show()
def create_simplest_animation() -> None:
figure = plt.figure()
def update_figure(i):
figure.clear()
_ = plt.plot(rng.normal(100, 15, 100))
plt.draw()
animation = FuncAnimation(figure, update_figure, 100)
# animation.save("simplest-function-animation.mp4", fps=1)
plt.show()
def main(argv: List[str]) -> None:
# Initialize the current locale.
locale.setlocale(locale.LC_ALL, '')
# Configure Seaborn visualization library.
sns.set_theme(style="darkgrid")
# dataset = sns.load_dataset("fmri")
# plot = sns.relplot(data=dataset.query("region == 'frontal'"), x="timepoint", y="signal", kind="line", hue="event", style="event", col="subject", col_wrap=7, height=4, aspect=0.75, label="Sample Text 1")
# plt.show()
# dataset = sns.load_dataset("penguins")
# plot = sns.relplot(data=dataset, x="bill_length_mm", y="bill_depth_mm", hue="body_mass_g", palette="crest")
# plot.set_axis_labels("Bill Length (mm)", "Bill Depth (mm)", labelpad=10)
# plot.legend.set_title("Body Mass (g)")
# plot.figure.set_size_inches(8.5, 5.0)
# plot.ax.set_title("Analysis of Penguin Bill Depth As a Function of Length")
# plot.ax.set_xmargin(0.15)
# plot.ax.set_ymargin(0.25)
# plot.tight_layout()
# plt.show()
# iq_scores = []
# samples = 10
# for _ in range(samples):
# iq_score = int(rng.normal(100, 15))
# iq_scores.append(iq_score)
# figure, axis = plt.subplots()
# _ = axis.hist(iq_scores, bins=60, density=False, align="mid", label="Overall IQ Scores")
# plt.show()
# seed = 42
# figure, axes = plt.subplots()
# frame_updater = UpdateFrame(axes, seed=seed)
# animation = FuncAnimation(figure, frame_updater, frames=250, interval=150, blit=False)
# plt.show()
# create_animation()
# create_simplest_animation()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment