Created
September 7, 2023 06:18
-
-
Save jflopezfernandez/bca170d837d51f9ae5811d81e5a76ee3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""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