0% encontró este documento útil (0 votos)
33 vistas25 páginas

CódigoPython GráficoLíneas

Codigo de python para introducirte en los graficos de lineas

Cargado por

Nati Andrade
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como TXT, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
33 vistas25 páginas

CódigoPython GráficoLíneas

Codigo de python para introducirte en los graficos de lineas

Cargado por

Nati Andrade
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como TXT, PDF, TXT o lee en línea desde Scribd

# -*- coding: utf-8 -*-

"""

@author: BHidalgo
"""
#%% LIBRERIAS COMUNES

import matplotlib.pyplot as plt


# Instalar: pip install matplotlib
import seaborn as sns
# Instalación: pip install seaborn
import matplotlib.dates as mdates
import pandas as pd
import numpy as np
# Instalación: pip install numpy
from datetime import datetime, timedelta

#%%
# =============================================================================
# GRÁFICOS DE LÍNEAS
# =============================================================================

#%% LIBRERIA MATPLOTLIB

# Crear data aleatoria


# np.random.randn -> Función que me genera 1000 numeros aletorios distribuidos
normalmente (media:0, dsv:1)
# Sin utilizar la suma acumulada
values = (np.random.randn(1000,1))
# np.cumsum me realiza la suma acumulada de mis valores para mostrarlos como una
serie de tiempo.
values = np.cumsum(np.random.randn(1000,1))

# Gráfico de Líneas con función PLOT


plt.plot(values)
plt.show() # Si están en Jupyter

#%% LIBRERIA SEABORN


import seaborn as sns
# Instalación: pip install seaborn

# Usar seaborn style


sns.set_theme()
# Desactivar el estilo seaborn
#sns.reset_orig()

# Crear data
values=np.cumsum(np.random.randn(1000,1))

# Gráfico de Líneas con función PLOT


plt.plot(values)

#%% GRÁFICO DE LÍNEAS CON DATA ORDENADA

# Crear un dataframe o una tabla de datos


df = pd.DataFrame({'xvalues':range(1,101), 'yvalues': np.random.randn(100)})

# Función <pd.DataFrame>: se utiliza para crear un dataframe. Donde las {} crean un


diccionario
# para la función DataFrame donde las claves son interpretadas como nombres de
columnas y
# los valores asociados a esas claves como datos para las columnas.

# Función <range>: genera una secuencia de números donde su sintaxis es:


# range(inicio, fin) donde fin = fin-1

# Diferencias entre <np.random.randn(100)> vs <np.random.randn(1000,1)>:


# La 1era genera un array unidimensional (1D) de longitud 100. Es decir, una
lista de
# 100 números aleatorios.
# La 2da genera un array bidimensional (2D) con 100 filas y 1 columna. Es decir,
una matriz
# con 100 elementos pero en una sola columna.

# Gráfico de Líneas con función PLOT


plt.plot('xvalues', 'yvalues', data=df)

# Argumentos:
# 1. 'xvalues', 'yvalues': Son los nombres de las columnas del DataFrame df que se
# utilizarán para el eje x e y, respectivamente.
# 2. data=df: Especifica el DataFrame que contiene los datos.
# Indica que las columnas 'xvalues' y 'yvalues' se toman del DataFrame df.

#%% GRÁFICO DE LÍNEAS PERSONALIZADO CON MATPLOTLIB

# =============================================================================
# # 1. PERSONALIZAR COLOR
# =============================================================================
# Argumento <color>
# Argumento <alpha>

# Crear un dataframe o una tabla de datos


df = pd.DataFrame({'x_values':range(1,11), 'y_values':np.random.randn(10)})

# Gráfico de Líneas con función PLOT


# Argumento <color>
# Colores como palabras
# https://python-charts.com/es/colores/
plt.plot('x_values', 'y_values', data=df, color='skyblue')
plt.plot('x_values', 'y_values', data=df, color='red')
plt.plot('x_values', 'y_values', data=df, color='r')
plt.plot('x_values', 'y_values', data=df, color='aqua')

# Colores como HEX


plt.plot('x_values', 'y_values', data=df, color='#D2B48C')

# Colores como RGB


plt.plot('x_values', 'y_values', data=df, color=(0.75, 0, 0.75))

# Gráfico de líneas modificando la transparencia de la línea


# Argumento: <alpha> que va de 0 a 1. Siendo 0: transparente y 1:color original.
plt.plot('x_values', 'y_values', data=df, color='red')
plt.plot('x_values', 'y_values', data=df, color='red', alpha=0.3)

# =============================================================================
# # 2. PERSONALIZAR ESTILO DE LINEA
# =============================================================================
# Argumento <linestyle>: Establece el estilo de la línea.
# Argumento <linewidth>: Establece el grosor de la línea.

# Gráfico de Líneas con función PLOT


plt.plot('x_values', 'y_values', data=df, linestyle='dashed')

# Otros tipos de estilos de líneas


plt.plot('x_values', 'y_values', data=df, color='r', linestyle='-', linewidth=4)
plt.plot('x_values', 'y_values', data=df, linestyle='--', linewidth=2.5)
plt.plot('x_values', 'y_values', data=df, linestyle='-.', linewidth=3)
plt.plot('x_values', 'y_values', data=df, linestyle=':', linewidth=7.5)

plt.plot('x_values', 'y_values', data=df, color="y", ls='--', lw=6.5)

#%% GRÁFICO DE LÍNEAS CON SERIES DE TIEMPO

# Lectura de data de la evolución del precio del Bitcoin entre 2013 y 2018
data = pd.read_csv(
"https://raw.githubusercontent.com/holtzy/data_to_viz/master/Example_dataset/
3_TwoNumOrdered.csv",
delim_whitespace=True)

# Función <pd.read_csv>: Función de pandas que permite leer datos de un archivo CSV
# (Comma-Separated Values) o desde una URL que apunta a datos en formato CSV.
# Argumento <delim_whitespace=True>: Indica a pandas que el delimitador en el
archivo
# es un espacio en blanco.
# Para delimitadores de coma o punto y coma se utiliza el argumento
# <delimiter=","> o <delimiter=";">

# =============================================================================
# # ¿Cómo validamos el tipo de columna de un dataframe?
# =============================================================================
# Es decir, validar que está en formato de texto, de fecha o de número.

# Columna <date> este en formato datetime


data.dtypes
data["date"] = pd.to_datetime(data["date"])

# =============================================================================
# ENFOQUES
# Enfoque 1: Gráficos estilo pyplot (Pyplot-Style)
# Enfoque 2: Gráficos Orientado a Objetos (OO-Style)
# =============================================================================
# 1. plt.plot(x, y): Es una interfaz más simple y directa. Útil para gráficos
rápidos y sencillos.
# 2. ax.plot(x, y): Interfaz orientada a objetos de Matplotlib, donde se crean
explicitamente
# figuras y ejes. útil para gráficos más complejos y personalizaciones
específicas.

# Enfoque 1 - Pyplot-Style:
plt.plot('date', 'value', data=data, linestyle='dashed')

# Enfoque 2 - OO-Style:
# Separar columnas en dos dataframes
date = data["date"] # Representa el eje X
value = data["value"] # Representa el eje Y
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot('date', 'value', data=data)

# EXPLICACION DE FUNCIONES Y ARGUMENTOS FIG,AX


# 1. <fig, ax = plt.subplots(figsize=(8, 6))>: Crea una figura <fig> y un conjunto
de ejes <ax>.
# La figura es el contenedor con todos los elementos del gráfico.
# Los ejes son los límites del gráfico.
# El argumento <figsize> especifica el tamaño de la figura en pulgadas (ancho,
alto).

# 2. <ax.plot(date, value);>: Utilizando los ejes de <ax> crea un gráfico de líneas


donde
# el eje X es <date> y el eje Y es <value>, respectivamente.

# ¿CÓMO FUNCIONA <SUBPLOTS>?


# Permite simplificar la creación de gráficos múltiples en una sola figura.
fig, ax = plt.subplots(2, 2, figsize=(8, 6))
# 'ax' es ahora una matriz 2x2 de ejes

# Puedes acceder a un eje específico para dibujar en él


ax[0, 0].plot(date, value, color="r")
ax[0, 1].plot(date, value, color="g")
ax[1, 0].plot(date, value, color="y")
ax[1, 1].plot(date, value)

# =============================================================================
# MANEJANDO FECHAS EN EL EJE X
# Matplotlib -> Módulo <dates>
# =============================================================================

import matplotlib.dates as mdates


# <mdates>: Módulo de matplotlib que nos permite trabajar con las fechas en el eje
X.
# Dispone de clases <Locator> y <Formatter> que se usan para ubicar marcas y
formatear
# etiquetas, respectivamente.

# 1. UTILIZANDO SOLO LA CLASE <LOCATOR>


# Vamos a dividir cada etiqueta del eje X en 12 meses
fig, ax = plt.subplots(figsize=(8, 6))

half_year_locator = mdates.MonthLocator(interval=12) # Creación del localizador


mensual.
ax.xaxis.set_major_locator(half_year_locator) # Localiza en el eje X mayor o
principal.

ax.plot(date, value, color='black')

# Explicación:
# <mdates.MonthLocator> es un localizador que ubica marcas de los meses en el eje
X.
# <interval=6> significa que se colocará una marca de mes cada 12 meses.

# 2. UTILIZANDO LAS CLASES <LOCATOR> y <FORMATTER>


# Vamos a dividir cada etiqueta del eje X en 6 meses, pero especificando el mes.
fig, ax = plt.subplots(figsize=(8, 6))

half_year_locator = mdates.MonthLocator(interval=6) # Locator


year_month_formatter = mdates.DateFormatter("%Y%m") # DateFormatter:
# (Año: 4 digitos, Mes: 2
digitos)

ax.xaxis.set_major_locator(half_year_locator) # Localiza en el eje X mayor o


principal.
ax.xaxis.set_major_formatter(year_month_formatter) # Da formato en el eje X mayor o
principal.

ax.plot(date, value)

# TENEMOS OTROS FORMATOS PARA <DATEFORMATTER>


# Año completo con cuatro dígitos, mes en texto:
# mdates.DateFormatter("%b %Y")
# Año completo con cuatro dígitos, mes con dos dígitos:
# mdates.DateFormatter("%Y%m")
# Año completo con cuatro dígitos, mes con dos dígitos, día con dos dígitos:
# mdates.DateFormatter("%Y-%m-%d")
# Formato abreviado de mes y año:
# mdates.DateFormatter("%b %Y")
# Día del mes, abreviatura del mes y año:
# mdates.DateFormatter("%d %b %Y")
# Día de la semana, día del mes, abreviatura del mes y año:
# mdates.DateFormatter("%a %d %b %Y")
# Hora completa con dos dígitos para horas y minutos:
# mdates.DateFormatter("%H:%M")

# 3. ROTACION DE ETIQUETAS DE LOS EJES CON <fig.autofmt_xdate()>


# Vamos a dividir cada etiqueta del eje X en 6 meses, pero rotando el eje X.
fig, ax = plt.subplots(figsize=(8, 6))

ax.xaxis.set_major_locator(half_year_locator) # Locator
ax.xaxis.set_major_formatter(year_month_formatter) # Formatter
ax.plot(date, value, color='r')

# Gira y alinea a la derecha las etiquetas del eje X.


# También mueve la parte inferior de los ejes hacia arriba para dejarles espacio.
fig.autofmt_xdate() # Utilizable con fechas en el eje X.

# 4. AÑADIR MARCAS MENORES (EJE X SECUNDARIO)


# Utilizamos nuevamente <mdates.MonthLocator>
# Al no especificar argumentos se entiende que <interval=1>

sns.reset_orig() # Desactivar el tema de Seaborn


fig, ax = plt.subplots(figsize=(8, 6))

monthly_locator = mdates.MonthLocator() # Creamos un nuevo localizar de mes


ax.xaxis.set_minor_locator(monthly_locator) # Creamos el eje secundario para el
nuevo locator
ax.xaxis.set_major_locator(half_year_locator) # Mantenemos el localizador semestral
ax.xaxis.set_major_formatter(year_month_formatter) # Mantenemos el localizador
semestral
ax.plot(date, value, color='m')
fig.autofmt_xdate()

# 5. MODIFIQUEMOS EL FORMATO DE LA FECHA CON LAS SINTAXIS ANTERIORES

# Ejemplo a obtener: June, 2018


month_year_formatter = mdates.DateFormatter("%b, %Y") # La coma es parte del
formato

fig, ax = plt.subplots(figsize=(8, 6))

monthly_locator = mdates.MonthLocator() # Creamos un nuevo localizar de mes


ax.xaxis.set_minor_locator(monthly_locator) # Creamos el eje secundario para el
nuevo locator
ax.xaxis.set_major_locator(half_year_locator) # Mantenemos el localizador semestral
ax.xaxis.set_major_formatter(month_year_formatter) # Mantenemos el localizador
semestral
ax.plot(date, value, color='aqua')

fig.autofmt_xdate()

#%% GRÁFICO DE LÍNEAS CON EJE "Y" SECUNDARIO

# Importar libreria de fechas


from datetime import datetime, timedelta
# Librería incluida en la biblioteca estándar de Python
# Permite trabajar con fechas, acceder a fechas, compararlas
# y realizar aritmética de fechas (suma o resta fechas).
# Más sobre la libería Datetime:
https://aprendeconalf.es/docencia/python/manual/datetime/

# Garantiza la reproducibilidad de números aleatorios.


rng = np.random.default_rng(1234)
# Si no les funciona el anterior código intentar con la versión anterior:
# rng = np.random.seed(1234)

# La función <default_rng> genera números aleatorios.


# El parametro <1234> es una semilla que indica al código que debe mantener los
números
# aleatorios generados si se corren de nuevo.

# =============================================================================
# CREACION DE 3 VARIABLES
# =============================================================================

fecha = [datetime(2019, 1, 1) + timedelta(i) for i in range(100)]


temperatura = np.arange(100) ** 2.5 / 10000 + rng.uniform(size=100)
precio = np.arange(120, 20, -1) ** 1.5 / 10 + rng.uniform(size=100)

# VARIABLE FECHA
# fecha = [datetime(2019, 1, 1) + timedelta(i) for i in range(100)]
# La función <datetime> crea fechas ingresando seis argumentos:
(<año>,<mes>,<día>,<hr>,<mins>,<segs>).
# Si no se ingresa la hora, la función asume como media noche: <00:00:00>.
# La función <timedelta(i)> me suma una cantidad i de días.
# <timedelta> se utiliza para representar una cantidad de tiempo.
# Sus argumentos son timedelta(dias, hrs, segs, msegs)
# Si quisieramos sumar en meses usaríamos <timedelta(days=30*i)>.
# El bucle <for i in range(100):> itera sobre los valores desde 0 hasta 99.
# En cada iteración, se agrega un nuevo timedelta a la fecha inicial.
# range(100) asume su valor inicial en 0, al no especificarlo.

# Ejemplo fecha y hora:


fecha_hora = datetime(2023, 5, 17, 14, 30, 0)
#¿Qué pasa si solo ingreso año y mes?
fecha1 = datetime(2023,2)

# VARIABLE TEMPERATURA SIMULADA


# temperatura = np.arange(100) ** 2.5 / 10000 + rng.uniform(size=100)
# La función arange genera una secuencia de números espaciados uniformemente en un
rango.
# np.arange(start,stop,step):
# start: Es opcional, si no se coloca se asume 0 como valor de inicio.
# stop: El valor final y no está incluído en la secuencia.
# step: El paso o intervalo de los valores de la secuencia. Si no se coloca
se asume 1.
# <np.arange(100)> crea una lista de número de 0 a 99.
# <**>: símbolo para representar una potencia (eleva el número al exponente 2.5).
# <rng.uniform(size=100)> es una lista de 100 números generados aleatoriamente
entre
# 0 y 1, utilizando el generador <rng> configurado anteriormente.

# VARIABLE PRECIO SIMULADO


# precio = np.arange(120, 20, -1) ** 1.5 / 10 + rng.uniform(size=100)
# np.arange(120,20,-1) nos crea una secuencia de números desde 120 hasta 21.
# El tercer argumento realiza el decremento de -1.

# DETALLE DE LA FÓRMULA
# Con la fórmula del número**2.5/10000 generamos temperaturas simuladas que
aumenten
# de manera no lineal por el exponente y al dividirlo tenemos número más
manejables.
# El componente de aleatoriedad rng introduce variabilidad a los datos.

# =============================================================================
# CREACION UN SUBPLOT DE 1X2
# =============================================================================

fig, axes = plt.subplots(1, 2, figsize=(12, 5))

axes[0].plot(fecha, temperatura)
axes[1].plot(fecha, precio)

# =============================================================================
# CREACION DEL EJE SECUNDARIO Y CON MISMO EJE X <ax.twinx()>
# =============================================================================

fig, ax1 = plt.subplots(figsize=(9, 6))

# Crear un segundo eje que comparta el mismo eje x


ax2 = ax1.twinx()
ax2.set_ylim(4, 20)

# La función <set_ylim> establece los valores límites del eje Y.


# Sintaxis: set_ylim(bottom, top) donde son los limites inferior y superior,
respectivamente.
fig, ax1 = plt.subplots(figsize=(8, 8))
ax2 = ax1.twinx()

ax1.plot(fecha, temperatura)
ax2.plot(fecha, precio)

# =============================================================================
# PERSONALIZACIÓN DE LOS EJES Y
# =============================================================================

color_temp = "#69b3a2" # Colores formato HEX


color_precio = "#3399e6"

fig, ax1 = plt.subplots(figsize=(8, 8))


ax2 = ax1.twinx()

ax1.plot(fecha, temperatura, color=color_temp, lw=3)


ax2.plot(fecha, precio, color=color_precio, lw=4)

ax1.set_xlabel('Fecha')
ax1.set_ylabel('Temperatura (Celsius °)', color=color_temp, fontsize=14)
ax1.tick_params(axis="y", labelcolor=color_temp) # Marcas en el eje

ax2.set_ylabel("Precio ($)", color=color_precio, fontsize=14)


ax2.tick_params(axis="y", labelcolor=color_precio) # Marcas en el eje

fig.suptitle("Relación entre la Temperatura y Precio", fontsize=20)


fig.autofmt_xdate()

#%% GRÁFICO DE LÍNEAS CON AREAS RELLENADAS

# =============================================================================
# CREACION DE 3 VARIABLES
# =============================================================================

tiempo = np.arange(12)
ingresos = np.array([5, 9, 6, 6, 10, 7, 6, 4, 4, 5, 6, 4])
gastos = np.array([6, 6, 8, 3, 6, 9, 7, 8, 6, 6, 4, 8])

# <np.array>: Función de NumPy que se utiliza para crear un arreglo NumPy o


lista/serie.

# =============================================================================
# CREACION DEL ÁREA DE RELLENO
# =============================================================================

fig, ax = plt.subplots(figsize=(8, 8))

ax.plot(tiempo, ingresos, color="green")


ax.plot(tiempo, gastos, color="red")

# Rellenar el área cuando ingresos > gastos con verde


ax.fill_between(
tiempo, ingresos, gastos, where=(ingresos > gastos),
interpolate=True, color="green", alpha=0.25,
label="Positivo"
)
# Rellenar el área cuando ingresos <= gastos con rojo
ax.fill_between(
tiempo, ingresos, gastos, where=(ingresos <= gastos),
interpolate=True, color="red", alpha=0.25,
label="Negativo"
)

ax.legend() # Función <legend> <muestra la etiqueta de los datos.

# Sintaxis de fill_between
# ax.fill_between(x, y1, y2=0, where=None, interpolate=False, **kwargs)
# x: Las coordenadas x de los puntos que definen la curva.
# y1: Las coordenadas y de la curva inferior.
# y2: Las coordenadas y de la curva superior (Por defecto, se asume 0 si no se
proporciona).
# where: Una condición booleana opcional que indica dónde aplicar el relleno.
# interpolate: Un booleano que indica si se debe interpolar entre los puntos
dados.
# **kwargs: Argumentos adicionales que se pueden pasar para personalizar la
# apariencia del relleno (como el color, alfa, etc.).

#%% GRÁFICO DE LÍNEAS CON ANOTACIONES

# =============================================================================
# CREACIÓN DE UNA TABLA DE DATOS ALEATORIOS
# =============================================================================

# Lista vacia para almacenar los años


fechas = []
# Bucle para el rango dado
for año in range(1970,2024):
fechas.append(str(año)) #str convierte a cadena de texto el año
# La función <append> agrega un elemento al final de una lista.

# Generar una variable aletoria


sample_size = 2024 - 1970 # Resta los dos años
variable = np.random.normal(100, # mean
15, # standard deviation
sample_size # sample size
)
# Sintaxis de <np.random.normal>: numpy.random.normal(media, desvStd, size=None).

# Crear tabla de datos con las dos variables creadas


df = pd.DataFrame({'date': fechas,
'value': variable})

# =============================================================================
# CREACIÓN DEL GRAFICO - ENFOQUE 1 (Pyplot-Style)
# =============================================================================

# Tamaño de la figura
plt.figure(figsize=(8, 6))

# Crear el gráfico de lineas


plt.plot('date', 'value', data=df, color='m') # Forma 1
#plt.plot(df['date'], df['value'], color='aqua') # Forma 2
# Añadir etiquetas a los ejes y titulo al gráfico
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Basic Line Chart')

# Girar las etiquetas del eje X en 45° para una mejor visibilidad
plt.xticks(rotation=45)

# =============================================================================
# CREACIÓN DEL GRAFICO - ENFOQUE 1 (Pyplot-Style) CON ANOTACIONES
# =============================================================================

'''
Vamos a añadir 3 tipos de anotaciones:
1. Línea de Referencia: la media, calculada con el método median() de pandas.
2. Círculo o Punto: el valor más alto, calculado con idxmax() de pandas
que calcula el index más alto.
3. Texto: un comentario que deseemos colocar!
'''

# Función <iloc>: Permite acceder a datos de filas o columnas especificas en un


# DataFrame usando indexación basada en números enteros.
# Significa "integer location".

# Tamaño de la figura
plt.figure(figsize=(8, 6))

# Crear el gráfico de lineas


plt.plot('date', 'value', data=df, color='m') # Forma 1
#plt.plot(df['date'], df['value'], color='aqua') # Forma 2

# Añadir etiquetas a los ejes y titulo al gráfico


plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Basic Line Chart')

# Girar las etiquetas del eje X en 45° para una mejor visibilidad
plt.xticks(rotation=45)

# Añadir una anotación de texto


plt.text(df['date'].iloc[38], # Posición eje X según el index
df['value'].iloc[21], # Posición eje Y según el index
'¡Excelente Gráfico!', # Texto
fontsize=13, # Tamaño del Texto
color='red') # Color del Texto

# Encontrar el index con el valor en value más alto


highest_index = df['value'].idxmax() # Devuelve la posición del index con el value
más alto.

# Añadir un circulo en el punto más alto


plt.scatter(df['date'].iloc[highest_index], # iloc me devuelve el valor del index
para fecha
df['value'].iloc[highest_index], # iloc me devuelve el valor del index
para value
color='blue',
marker='o', # Formato para especificar un circulo
s=100, # Tamaño del market (aplica solo en gráficos de scatter)
)

# Calcular el mediana
median_value = df['value'].median()

# Añadir la línea referencia con <axhline>


plt.axhline(y=median_value, color='green', linestyle='--', label='Línea Referencial
(mediana)')
# Sintaxis de <axhline>:
# plt.axhline(y=0, xmin=0, xmax=1, color='k', linestyle='--', linewidth=2)
# y: La posición en el eje Y donde se colocará la línea horizontal.
# xmin y xmax: Los valores en eje X que especifican los extremos de la línea
# horizontal.

'''
Formatos de marker:
'o': Círculo
's': Cuadrado
'D': Diamante
'^': Triángulo hacia arriba
'v': Triángulo hacia abajo
'<': Triángulo hacia la izquierda
'>': Triángulo hacia la derecha
'p': Pentágono
'*': Estrella
'+': Signo de más
'x': Cruz
'h': Hexágono
'''

#%% GRÁFICO DE LINEAS CON VARIOS GRUPOS

# Data
df = pd.DataFrame({'x_values': range(1,11),
'y1_values': np.random.randn(10),
'y2_values': np.random.randn(10)+range(1,11),
'y3_values': np.random.randn(10)+range(11,21)})

# =============================================================================
# MÚLTIPLES LÍNEAS EN UN SOLO GRAFICO
# =============================================================================

plt.plot( 'x_values', 'y1_values', data=df, marker='o', markerfacecolor='blue',


markersize=12, color='skyblue', linewidth=4)
plt.plot( 'x_values', 'y2_values', data=df, marker='', color='olive', linewidth=2)
plt.plot( 'x_values', 'y3_values', data=df, marker='', color='olive', linewidth=2,
linestyle='--', label="toto")

# show legend
plt.legend()

# =============================================================================
# RESALTAR UNA LINEA EN UN GRAFICO
# =============================================================================

# Crear un dataframe con 8 variables Y.


df = pd.DataFrame({'x': range(1,11),
'y1': np.random.randn(10),
'y2': np.random.randn(10)+range(1,11),
'y3': np.random.randn(10)+range(11,21),
'y4': np.random.randn(10)+range(6,16),
'y5': np.random.randn(10)+range(4,14)+(0,0,0,0,0,0,0,-3,-8,-6),
'y6': np.random.randn(10)+range(2,12),
'y7': np.random.randn(10)+range(5,15),
'y8': np.random.randn(10)+range(4,14)})

# Cambiar el estilo del gráfico


plt.style.use('seaborn-darkgrid')

# Configurar el tamaño y resolución de la imagen


my_dpi = 96
plt.figure(figsize=(480/my_dpi, 480/my_dpi), dpi=my_dpi)

# Opción 1 para gráficar múltiples líneas


# Graficar múltiples líneas
for column in df.drop('x', axis=1): # Gráfica todas las columnas desde Y1 a Y8 sin
la columna de X.
plt.plot(df['x'], df[column], marker='', color='grey', linewidth=1, alpha=0.4)

# Opción 2 para gráficas múltiples líneas


# Gráficar línea por línea
# plt.plot('x', 'y1', data=df, marker='', color='grey', linewidth=1, alpha=0.4)
# plt.plot('x', 'y2', data=df, marker='', color='grey', linewidth=1, alpha=0.4)
# plt.plot('x', 'y3', data=df, marker='', color='grey', linewidth=1, alpha=0.4)
# ...

# Resaltar la línea de interes, en este caso es Y5


plt.plot(df['x'], df['y5'], marker='', color='orange', linewidth=4, alpha=0.7)

# Personalizando los puntos de datos


#plt.plot(df['x'], df['y5'], marker='h', markersize=10, markerfacecolor='red',
color='orange', linewidth=4, alpha=0.7)

# Cambiar el tamaño del eje X


plt.xlim(0,12)

# Opción 1 para colocar las etiquetas en cada línea. Excepción de Y5.


num=0
for i in df.values[9][1:]: # <df.values[9][1:]> Escoge la última fila desde la
columna 2.
num+=1 # Posiciona el nombre de la columna
name=list(df)[num] # Genera el nombre de la columna
if name != 'y5': # No aplica para la columna Y5
plt.text(10.2, i, name, horizontalalignment='left', size='small',
color='grey')

# Añadir etiqueta para línea de interes Y5


plt.text(10.2, df.y5.tail(1), 'Mr Orange', horizontalalignment='left',
size='small', color='orange')

df.tail(2)

# Opción 2 para colocar las etiquetas en cada línea.


# plt.text(10.2, df.y1.tail(1), 'y1', horizontalalignment='left', size='small',
color='grey')
# plt.text(10.2, df.y2.tail(1), 'y2', horizontalalignment='left', size='small',
color='grey')
# plt.text(10.2, df.y3.tail(1), 'y3', horizontalalignment='left', size='small',
color='grey')
# plt.text(10.2, df.y4.tail(1), 'y4', horizontalalignment='left', size='small',
color='grey')
# plt.text(10.2, df.y5.tail(1), 'Mr Orange', horizontalalignment='left',
size='small', color='orange')

# Add titles
plt.title("Evolution of Mr Orange vs other students", loc='left', fontsize=12,
fontweight='bold', color='orange')
plt.xlabel("Time")
plt.ylabel("Score")

# Explicación código
# my_dpi = 96
# plt.figure(figsize=(480/my_dpi, 480/my_dpi), dpi=my_dpi)
# Esta línea de código crea una figura con un tamaño específico (480x480 píxeles)
# y una resolución de 96 puntos por pulgada (dpi). Ajustar la resolución de la
figura puede
# ser útil al guardar la figura en un archivo, ya que afecta la calidad y el
tamaño del mismo.
# <dpi> significa "dots per inch" (puntos por pulgada), y se refiere a la
resolución de la imagen.

# Personalizar los marcadores o puntos de datos de unión de líneas


# <marker='h'> Me genera el tipo de marcador, en este caso un hexágono.
# <markersize=10> Me genera el tamaño del marcador. Su abreviatura es <ms>.
# <markerfacecolor='red'> Me establece el color. Su abreviatura es <mfc>.

# =============================================================================
# GENERAR UN GRAFICO DE SPAGUETTI CON PALETA DE COLORES
# =============================================================================

# Crear un dataframe con 10 variables Y.


df=pd.DataFrame({'x': range(1,11),
'y1': np.random.randn(10),
'y2': np.random.randn(10)+range(1,11),
'y3': np.random.randn(10)+range(11,21),
'y4': np.random.randn(10)+range(6,16),
'y5': np.random.randn(10)+range(4,14)+(0,0,0,0,0,0,0,-3,-8,-6),
'y6': np.random.randn(10)+range(2,12),
'y7': np.random.randn(10)+range(5,15),
'y8': np.random.randn(10)+range(4,14),
'y9': np.random.randn(10)+range(4,14),
'y10': np.random.randn(10)+range(2,12) })

# Cambiar el estilo del gráfico


plt.style.use('seaborn-darkgrid')

# Crear una paleta de colores


palette = plt.get_cmap('Set3')
# Tenemos varios Sets de paletas de colores:
# Set1: Paleta con 9 colores distintos.
# Set2: Paleta con 8 colores distintos.
# Set3: Paleta con 12 colores distintos.

# Graficar las líneas múltiples


num=0
for column in df.drop('x', axis=1):
num+=1
plt.plot(df['x'], df[column], marker='', color=palette(num), linewidth=1,
alpha=0.9, label=column)

# Add legend
plt.legend(loc=2, ncol=2)
#plt.legend()
#plt.legend(loc=0, ncol=2)

# <loc> especifica la ubicación de la leyenda en el gráfico.


# 0: Mejor ubicación automática.
# 1: Parte superior derecha.
# 2: Parte superior izquierda.
# 3: Parte inferior izquierda.
# 4: Parte inferior derecha.
# <ncol> especifica el número de columnas de la leyenda

# Add titles
plt.title("Un Gráfico (Erróneo) de Spaguetti", loc='left', fontsize=12,
fontweight=0, color='orange')
plt.xlabel("Tiempo")
plt.ylabel("Calificación")

# =============================================================================
# GRAFICO CON SUBPLOTS
# =============================================================================

# Crear el dataframe
df=pd.DataFrame({'x': range(1,11),
'y1': np.random.randn(10),
'y2': np.random.randn(10)+range(1,11),
'y3': np.random.randn(10)+range(11,21),
'y4': np.random.randn(10)+range(6,16),
'y5': np.random.randn(10)+range(4,14)+(0,0,0,0,0,0,0,-3,-8,-6),
'y6': np.random.randn(10)+range(2,12),
'y7': np.random.randn(10)+range(5,15),
'y8': np.random.randn(10)+range(4,14),
'y9': np.random.randn(10)+range(4,14) })

# Estilo del gráfico


plt.style.use('seaborn-darkgrid')

# Crear una paleta de color


palette = plt.get_cmap('Set3')

# Gráfico de múltiple líneas


num=0
for column in df.drop('x', axis=1):
num+=1

# Encuentra el lugar correcto en el gráfico


plt.subplot(3,3, num) # num especifica el indice del subgrafico
# Si num=1 la posición es [1,1]
# Si num=2 la posición es [1,2]
# Si num=4 la posición es [2,1]
# Si num=8 la posición es [3,2]

# Gráficar las líneas de forma discreta


for v in df.drop('x', axis=1):
plt.plot(df['x'], df[v], marker='', color='grey', linewidth=0.6, alpha=0.3)

# Gráficar la línea de interes en el área


plt.plot(df['x'], df[column], marker='', color=palette(num), linewidth=1.9,
alpha=0.9, label=column)

# Establecer límites en X & Y


plt.xlim(0,10)
plt.ylim(-2,22)

# Añadir título a los subplots


plt.title(column, loc='left', fontsize=12, fontweight='bold',
color=palette(num))

# Título general de la figura


plt.suptitle("How the 9 students improved\nthese past few days?", fontsize=13,
fontweight=0, color='black', style='italic', y=1.02)

# Axis titles
plt.text(0.06, 0.02, 'Time', ha='left', va='center')
plt.text(0.06,15, 'Note', ha='left', va='bottom', rotation='vertical')

'''
Parametros para los argumentos

1. horizontalalignment (alineación horizontal):


'left': Alinea el texto a la izquierda.
'center': Alinea el texto en el centro horizontal.
'right': Alinea el texto a la derecha.

2. size: tamaño del texto


'small'
'medium'
'large'
Valores númericos como <size=12> para un tamaño específico.

3. fontstyle: estilo de texto (negrita, cursiva, subrayado, etc.):


'italic' -> Texto en cursiva
'normal' -> Fuente predeterminado
'oblique' -> Similar a cursiva

4. fontweight: estilo de fuente (normal, negrita, delgada, etc.):


'normal' -> predeterminado
'bold' -> negrita
'light' -> texto más ligero que el predeterminado
'semibold' -> seminegrita

5. verticalalignment (alineación vertical):


'top'
'center'
'bottom'

'''

#%% FORMAS DE ESCRIBIR EL CODIGO DE PLOT

# OPCIÓN 1:
# Aquí disponemos de una variable llamada <values>, que se graficará en el eje Y.
# El eje X será el total de valores en Y: 0 a 1000.
# La variable <values> es una lista de datos.
values = (np.random.randn(1000,1))
plt.plot(values)

# OPCIÓN 2:
# Aquí disponemos de dos columnas de una variable llamada <df>. Está variable es
una tabla.
df = pd.DataFrame({'xvalues':range(1,101), 'yvalues': np.random.randn(100)})
plt.plot('xvalues', 'yvalues', data=df)
plt.plot('x_values', 'y_values', data=df, color='r', linestyle='-', linewidth=4)

# OPCIÓN 3:
# Aquí separamos las columnas del dataframe en dos variables
date = data["date"] # Representa el eje X
value = data["value"] # Representa el eje Y

fig, ax = plt.subplots(figsize=(8, 6))


ax.plot(date, value)
#ax.plot('date', 'value', data=data) # Opción 2

# Opción 4:
plt.plot(df['x'], df['y5'], marker='', color='orange', linewidth=4, alpha=0.7)

#%% GRÁFICOS PERSONALIZADOS - EJEMPLO 1

# Today's chart visualizes the price changes (in USD) of a Big Mac based on a 2008
as index year.
# The original source of the data is TheEconomist, but this blog is based on the
version released
# for the TidyTuesday initiative on the week of 2020-12-22.

df_mac_raw = pd.read_csv(
"https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/
2020/2020-12-22/big-mac.csv")

# A list of country/zones that are going to be highlighted


HIGHLIGHTS = ["EUZ", "CHE", "DNK", "SWE", "BRA", "ARG", "GBR", "USA"]

# Extract year
df_mac_raw["year"] = pd.DatetimeIndex(df_mac_raw["date"]).year

# Subset variables
df_mac_raw = df_mac_raw[["date", "year", "iso_a3", "currency_code", "name",
"dollar_price"]]

# If there is more than one record per year/country, use the mean
df_mac = df_mac_raw.groupby(["iso_a3", "name", "year"]).agg(price =
("dollar_price", "mean")).reset_index()

# Keep countries/regions with records for the last 21 years


# (from 2000 to 2020 inclusive)
group_sizes = df_mac.groupby("iso_a3").size()
keep = (group_sizes[group_sizes == 21]).index.tolist()
df_mac = df_mac[df_mac["iso_a3"].isin(keep)]

# Keep countries that have a record for 2008, the index year.
countries = df_mac[df_mac["year"] == 2008]["iso_a3"].tolist()
df_mac_indexed_2008 = df_mac[df_mac["iso_a3"].isin(countries)]
df_mac_indexed_2008["ref_year"] = 2008

# For each country/region, obtain the price for 2008


df_price_index = df_mac_indexed_2008.groupby("iso_a3").apply(
lambda x: x.iloc[np.where(x["year"] == 2008)]
).reset_index(drop=True)

# Rename this price to 'price_index'


df_price_index.rename(columns={"price": "price_index"}, inplace=True)

# Keep only 'iso_a3' and 'price_index' in this auxiliary table


df_price_index = df_price_index[["iso_a3", "price_index"]]

# Merge the index price


df_mac_indexed_2008 = pd.merge(df_mac_indexed_2008, df_price_index, on = "iso_a3")

# Compute relative price


df_mac_indexed_2008["price_rel"] = df_mac_indexed_2008["price"] -
df_mac_indexed_2008["price_index"]

# Create 'group' to determine which ones are highlighted


df_mac_indexed_2008["group"] = np.where(
df_mac_indexed_2008["iso_a3"].isin(HIGHLIGHTS),
df_mac_indexed_2008["iso_a3"],
"other"
)

# Make 'group' categorical


df_mac_indexed_2008["group"] = pd.Categorical(
df_mac_indexed_2008["group"],
ordered=True,
categories=sorted(HIGHLIGHTS) + ["other"]
)

# =============================================================================
# GRAFICAR LINEAS
# =============================================================================

# Shades of gray
GREY10 = "#1a1a1a"
GREY30 = "#4d4d4d"
GREY40 = "#666666"
GREY50 = "#7f7f7f"
GREY60 = "#999999"
GREY75 = "#bfbfbf"
GREY91 = "#e8e8e8"
GREY98 = "#fafafa"

# Colors used to shade countries


COLOR_SCALE = [
"#7F3C8D", # ARG
"#11A579", # BRA
"#3969AC", # CHE
"#F2B701", # DNK
"#E73F74", # EUZ
"#80BA5A", # GBR
"#E68310", # SWE
GREY50 # USA
]

# Vertical lines every 5 years


VLINES = np.arange(2000, 2025, 5)

# Initialize layout ----------------------------------------------


fig, ax = plt.subplots(figsize = (14, 8.5))

# Background color
fig.patch.set_facecolor(GREY98)
ax.set_facecolor(GREY98)

# Vertical lines used as scale reference


for h in VLINES:
ax.axvline(h, color=GREY91, lw=0.6, zorder=0)

# Horizontal lines
ax.hlines(y=np.arange(-4, 4), xmin=2000, xmax=2020, color=GREY91, lw=0.6)

# Darker horizontal line at y=0


ax.hlines(y=0, xmin=2000, xmax=2020, color=GREY60, lw=0.8)

# Vertical like at x = 2008


ax.axvline(2008, color=GREY40, ls="dotted")

# Annotations indicating the meaning of the vertical line


ax.text(2008.15, -3.35, "2008", fontname="Montserrat",
fontsize=14, fontweight=500, color=GREY40, ha="left")

# Add lines ------------------------------------------------------


# Create one data frame for the highlighted countries, and other
# for non-highlighted countries.
df_highlight = df_mac_indexed_2008[df_mac_indexed_2008["group"] != "other"]
df_others = df_mac_indexed_2008[df_mac_indexed_2008["group"] == "other"]

for group in df_others["iso_a3"].unique():


data = df_others[df_others["iso_a3"] == group]
ax.plot("year", "price_rel", c=GREY75, lw=1.2, alpha=0.5, data=data)

for idx, group in enumerate(df_highlight["iso_a3"].unique()):


data = df_highlight[df_highlight["iso_a3"] == group]
color = COLOR_SCALE[idx]
ax.plot("year", "price_rel", color=color, lw=1.8, data=data)

# =============================================================================
# AÑADIR ETIQUETAS
# =============================================================================

# First, adjust axes limits so annotations fit in the plot


ax.set_xlim(2000, 2024.5)
ax.set_ylim(-4.1, 3)

# Positions
LABEL_Y = [
-0.45, # ARG
-0.15, # BRA
0.5, # CHE
-1.7, # DNK
-0.75, # EUZ
0.15, # GBR
-1.05, # SWE
2.1 # USA
]

x_start = 2020
x_end = 2021
PAD = 0.1

# Add labels for highlighted countries only


for idx, group in enumerate(df_highlight["iso_a3"].unique()):
data = df_highlight[(df_highlight["iso_a3"] == group) & (df_highlight["year"]
== 2020)]
color = COLOR_SCALE[idx]

# Country name
text = data["name"].values[0]

# Vertical start of line


y_start = data["price_rel"].values[0]
# Vertical end of line
y_end = LABEL_Y[idx]

# Add line based on three points


ax.plot(
[x_start, (x_start + x_end - PAD) / 2 , x_end - PAD],
[y_start, y_end, y_end],
color=color,
alpha=0.5,
ls="dashed"
)

# Add country text


ax.text(
x_end,
y_end,
text,
color=color,
fontsize=14,
weight="bold",
fontfamily="Montserrat",
va="center"
)
fig

# =============================================================================
# FINALIZACIÓN DEL GRAFICO: PERSONALIZANDO TITULO E INSIGHTS
# =============================================================================

# Customize axes labels and ticks --------------------------------


ax.set_yticks([y for y in np.arange(-4, 4)])
ax.set_yticklabels(
[f"{y}.00$" for y in np.arange(-4, 4)],
fontname="Montserrat",
fontsize=11,
weight=500,
color=GREY40
)
ax.set_xticks([x for x in np.arange(2000, 2025, 5)])
ax.set_xticklabels(
[x for x in np.arange(2000, 2025, 5)],
fontname= "Montserrat",
fontsize=13,
weight=500,
color=GREY40
)

# Increase size and change color of axes ticks


ax.tick_params(axis="x", length=12, color=GREY91)
ax.tick_params(axis="y", length=8, color=GREY91)

# Customize spines
ax.spines["left"].set_color(GREY91)
ax.spines["bottom"].set_color(GREY91)
ax.spines["right"].set_color("none")
ax.spines["top"].set_color("none")

# Add titles, subtitles, and caption -----------------------------


# This uses `fig.text()` instead of regular titles to have full
# control of the text alignment.
subtitle = [
"The index chart visualizes the price changes (in USD) of a Big Mac based on a
2008 as index year. The Big Mac Index is published by The Economist as an informal
way to provide",
"a test of the extent to which market exchange rates result in goods costing
the same in different countries. It seeks to make exchange-rate theory a bit more
digestible and takes,",
"its name from the Big Mac a hamburger sold at McDonald's restaurants",
]

fig.text(
0.08,
0.97,
"Compared to the financial crisis in 2008, how much more or less do you have to
pay for a Big Mac today?",
color=GREY10,
fontsize=15,
fontname="Montserrat",
weight="bold"
)

fig.text(
0.08,
0.91,
"\n".join(subtitle),
ha="left",
color=GREY30,
fontname="Montserrat",
fontsize=9,
)

fig.text(
0.08,
0.05,
"Visualization by Cédric Scherer • Data by The Economist • The index chart
shows the 27 countries that provide Big mac prices for all years from 2000 to 2020.
In case a country was reported twice per year, the mean value was visualized.",
fontname="Montserrat",
fontsize=6.5,
color=GREY30,
ha="left"
)

fig

#%% GRÁFICOS PERSONALIZADOS - EJEMPLO 2

# Open the dataset from Github


url = "https://raw.githubusercontent.com/holtzy/the-python-graph-gallery/master/
static/data/dataConsumerConfidence.csv"
df = pd.read_csv(url)

# Reshape the DataFrame using pivot longer


df = df.melt(id_vars=['Time'], var_name='country', value_name='value')

# Convert to time format


df['Time'] = pd.to_datetime(df['Time'], format='%b-%Y')

# Remove rows with missing values (only one row)


df = df.dropna()

# =============================================================================
# GRAFICAR UNA FIGURA DE 3X3
# =============================================================================

# Create a colormap with a color for each country


num_countries = len(df['country'].unique())
colors = plt.cm.get_cmap('tab10', num_countries)

# Init a 3x3 charts


fig, ax = plt.subplots(nrows=3, ncols=3, figsize=(6, 10))

# Plot each group in the subplots


for i, (group, ax) in enumerate(zip(df['country'].unique(), ax.flatten())):

# Filter for the group


filtered_df = df[df['country'] == group]
other_groups = df['country'].unique()[df['country'].unique() != group]

# Plot other groups with lighter colors


for other_group in other_groups:

# Filter observations that are not in the group


other_y = df['value'][df['country'] == other_group]
other_x = df['Time'][df['country'] == other_group]

# Display the other observations with less opacity


ax.plot(other_x, other_y, color=colors(i))

# Plot the line of the group


x = filtered_df['Time']
y = filtered_df['value']
ax.plot(x, y, color='black')

# Removes spines
ax.spines[['right', 'top', 'left', 'bottom']].set_visible(False)

# Remove axis labels


ax.set_yticks([])
ax.set_xticks([])

# Add a bold title to each subplot


ax.set_title(f'{group}', fontsize=12)

# Adjust layout and spacing


plt.tight_layout()

# =============================================================================
# AÑADIR OPACIDAD Y MEJORAR EL ESTILO
# =============================================================================

# Create a colormap with a color for each country


num_countries = len(df['country'].unique())
colors = plt.cm.get_cmap('tab10', num_countries)

# Init a 3x3 charts


fig, ax = plt.subplots(nrows=3, ncols=3, figsize=(8, 12))

# Plot each group in the subplots


for i, (group, ax) in enumerate(zip(df['country'].unique(), ax.flatten())):

# Filter for the group


filtered_df = df[df['country'] == group]
x = filtered_df['Time']
y = filtered_df['value']

# Set the background color for each subplot


ax.set_facecolor('seashell')
fig.set_facecolor('seashell')

# Plot the line


ax.plot(x, y, color=colors(i))

# Plot other groups with lighter colors (alpha argument)


other_groups = df['country'].unique()[df['country'].unique() != group]
for other_group in other_groups:

# Filter observations that are not in the group


other_y = df['value'][df['country'] == other_group]
other_x = df['Time'][df['country'] == other_group]

# Display the other observations with less opacity (alpha=0.2)


ax.plot(other_x, other_y, color=colors(i), alpha=0.2)

# Removes spines
ax.spines[['right', 'top', 'left', 'bottom']].set_visible(False)

# Add a bold title to each subplot


ax.set_title(f'{group}', fontsize=12, fontweight='bold')

# Remove axis labels


ax.set_yticks([])
ax.set_xticks([])
# Adjust layout and spacing
plt.tight_layout()

# =============================================================================
# AÑADIR ANOTACIONES
# =============================================================================

# Create a colormap with a color for each country


num_countries = len(df['country'].unique())
colors = plt.cm.get_cmap('tab10', num_countries)

# Init a 3x3 charts


fig, ax = plt.subplots(nrows=3, ncols=3, figsize=(8, 12))

# Add a big title on top of the entire chart


fig.suptitle('\nConsumer \nConfidence \nAround the \nWorld\n\n', # Title ('\n'
allows you to go to the line),
fontsize=40,
fontweight='bold',
x=0.05, # Shift the text to the left
ha='left' # Align the text to the left
)

# Add a paragraph of text on the right of the title


paragraph_text = (
"The consumer confidence indicator\n"
"provided an indication of future\n"
"developments of households'.\n"
"consumption and saving. An\n"
"indicator above 100 signals a boost\n"
"in the consumers' confidence\n"
"towards the future economic\n"
"situation. Values below 100 indicate\n"
"a pessimistic attitude towards future\n"
"developments in the economy,\n"
"possibly resulting in a tendency to\n"
"save more and consume less. During\n"
"2022, the consuer confidence\n"
"indicators have declined in many\n"
"major economies around the world.\n"
)
fig.text(0.55, 0.9, # Position
paragraph_text, # Content
fontsize=12,
va='top', # Put the paragraph at the top of the chart
ha='left', # Align the text to the left
)

# Plot each group in the subplots


for i, (group, ax) in enumerate(zip(df['country'].unique(), ax.flatten())):

# Filter for the group


filtered_df = df[df['country'] == group]
x = filtered_df['Time']
y = filtered_df['value']

# Get last value (according to 'Time') for the group


sorted_df = filtered_df.sort_values(by='Time')
last_value = sorted_df.iloc[-1]['value']
last_date = sorted_df.iloc[-1]['Time']

# Set the background color for each subplot


ax.set_facecolor('seashell')
fig.set_facecolor('seashell')

# Plot the line


ax.plot(x, y, color=colors(i))

# Add the final value


ax.plot(last_date, # x-axis position
last_value, # y-axis position
marker='o', # Style of the point
markersize=5, # Size of the point
color=colors(i), # Color
)

# Add the text of the value


ax.text(last_date,
last_value*1.005, # slightly shift up
f'{round(last_value)}', # round for more lisibility
fontsize=7,
color=colors(i), # color
fontweight='bold',
)

# Add the 100 on the left


ax.text(sorted_df.iloc[0]['Time'] - pd.Timedelta(days=300), # shift the
position to the left
100,
'100',
fontsize=10,
color='black',)

# Add line
sorted_df = df.sort_values(by='Time')
start_x_position = sorted_df.iloc[0]['Time']
end_x_position = sorted_df.iloc[-1]['Time']
ax.plot([start_x_position, end_x_position], # x-axis position
[100, 100], # y-axis position (constant position)
color='black', # Color
alpha=0.8, # Opacity
linewidth=0.8, # width of the line
)

# Plot other groups with lighter colors (alpha argument)


other_groups = df['country'].unique()[df['country'].unique() != group]
for other_group in other_groups:

# Filter observations that are not in the group


other_y = df['value'][df['country'] == other_group]
other_x = df['Time'][df['country'] == other_group]

# Display the other observations with less opacity (alpha=0.2)


ax.plot(other_x, other_y, color=colors(i), alpha=0.2)

# Removes spines
ax.spines[['right', 'top', 'left', 'bottom']].set_visible(False)
# Add a bold title to each subplot
ax.set_title(f'{group}', fontsize=12, fontweight='bold')

# Remove axis labels


ax.set_yticks([])
ax.set_xticks([])

# Add a credit section at the bottom of the chart


fig.text(0.0, -0.01, # position
"Design:", # text
fontsize=10,
va='bottom',
ha='left',
fontweight='bold',)
fig.text(0.1, -0.01, # position
"Gilbert Fontana", # text
fontsize=10,
va='bottom',
ha='left')
fig.text(0.0, -0.025, # position
"Data:", # text
fontsize=10,
va='bottom',
ha='left',
fontweight='bold',)
fig.text(0.07, -0.025, # position
"OECD, 2022",
fontsize=10,
va='bottom',
ha='left')

# Adjust layout and spacing


plt.tight_layout()

También podría gustarte