Saltar al contingut

Matplotlib

Matplotlib és una biblioteca que serveix per dibuixar figures, funcions i tot tipus de gràfiques en imatges estàtiques.

Matplotlib és una llibreria de baix nivell que serveix per dibuixar figures, funcions i tota mena de gràfiques estàtiques (en imatges png).

Funciona molt bé amb estructures de Python, arrays de Numpy , sèries i dataFrames de Polars, etc.

Tot i que hi ha llibreries estàtiques més modernes i senzilles a Python (Seaborn) i altres que ofereixen gràfics animats (Plotly, Bokeh) ens interessa aprendre com funciona Matplotlib, perquè és la que ofereix el màxim nivell de personalització i perquè totes aquestes llibreries tenen un funcionament similar a Matplotlib.

Per aquest motiu, encara hi ha molts treballs científics que presenten les funcions i gràfics amb Matplotlib.

Crea un nou projecte amb UV:

Terminal window
uv init plod
cd plot
uv add matplotlib numpy

Modifica el fitxer main.py:

main.py
import matplotlib.pyplot as plt
xs = [2, 1, 5, 7, 11, 12, 15, 13]
plt.plot(xs)
plt.show()

Executa el fitxer:

Pots veure que quan s’executa plt.show() s’obre un panell amb el gràfic

Una altra opció és guardar el gràfic en un fitxer amb savefig:

main.py
import matplotlib.pyplot as plt
xs = [2, 1, 5, 7, 11, 12, 15, 13]
plt.plot(xs)
plt.savefig("plot.png")

Obre el fitxer plot.png:

Pots veure que s’ha generat un gràfic de la seqüència xs.

Crear gràfics de senzills amb el mètode plot()

Section titled “Crear gràfics de senzills amb el mètode plot()”

El gràfic més senzill que podem crear és una línia a partir d’una matriu plana (1D) o una llista.

En importar, ja creem un contenidor (un canvas = un llenç) dins de l’objecte plt.

El mètode plot és el que dibuixa el gràfic dins del contenidor plt.

Si no li diem res més, crea un gràfic de punts amb les dades de la llista que li hem passat.

main.py
import matplotlib.pyplot as plt
l1 = [2, 1, 5, 7, 11, 12, 15, 13]
plt.plot(l1)
plt.show()

També podem crear un gràfic amb diverses línies (una des d’un array 1D i una altra des d’una línia)

import numpy as np
import matplotlib.pyplot as plt
a1 = np.arange(2,17,2)
l1 = [2, 1, 5, 7, 11, 12, 15, 13]
plt.plot(l1)
plt.plot(a1)
plt.show()

També pots veure com crear una matriu i dibuixar una recta i posar-li punts a damunt.

main.py
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 5, 20)
y = np.linspace(0, 10, 20)
plt.plot(x, y, color = 'purple') # linia
plt.plot(x, y, 'o') # punts
plt.show()

Amb Matplotlib, pots accedir a un enorme ventall d’opcions de visualització 2D i fins i tot 3D. En aquest cas mostrem una ona sinusoidal radial.

Com a curiositat, aquesta funció es pot descriure matemàticament com:

Z = sin(R) on R = sqrt{X^2 + Y^2}

Desglossem-ho una mica més:

  • R és la distància euclidiana (equivalent al teorema de Pitàgores) des de l’origen (0, 0) fins a qualsevol punt ((X, Y)) en el pla.

  • La funció sin(R) pren aquesta distància radial i calcula el valor del sinus d’aquesta distància.

Les ones sinusoidals radials són útils per modelar fenòmens que es propaguen radialment des d’un punt central, com ara les ones de calor o electromagnètiques.

Aquest tipus de visualització només la mostrem com a demostració del potencial de la biblioteca.

import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
# Vectors de coordenades
X = np.arange(-5, 5, 0.15)
Y = np.arange(-5, 5, 0.15)
# Els transformem a matriu de coordenades.
X, Y = np.meshgrid(X, Y)
# Apliquem les funcions
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='viridis')
plt.show()

Els més importants i comuns en tots els gràfics són:

xEstructura de dades (llista, diccionari, array, dataframe …) on es troben les dades a dibuixar. Necessari.
yDimensió Y per figures 2D i gràfics de funcions que representin linies (siguin rectes o no) o punts en un pla.
zDimensió Z per gràfics 3D.
colorColor dels punts/rectes/figures.
labelposem llegenda a la línia.
fmtformat. Si tenim números decimals

Si no li diem res, la funció infereix els paràmetres (sobretot els x, y que són molt habituals), però és bona pràctica especificar paràmetres.

A part dels paràmetres de la funció plot, tenim altres mètodes importants dins el contenidor del gràfic (plt en el nostre cas).

Els més bàsics són els que mostren les etiquetes dels eixos i del títol del gràfic.

  • ylabel(“Etiqueta eix vertical”)
  • xlabel(“Etiqueta eix horitzontal”)
  • title(“Titol gràfic”)
  • legend() —> Mostra una llegenda de les funcions o barres
  • grid() —> Mostra una graella per facilitar la visió

I com fer el gràfic més gran o més petit? Podem usar aquest mètode abans de mostrar o guardar el gràfic, que indica les proporcions:

plt.figure(figsize=(10,6))

Usant els arrays de Numpy i llistes, podem crear gràfics de diverses línies.

Per exemple, l’evolució de vendes de 3 models de targetes gràfiques en 4 mesos.

import matplotlib.pyplot as plt
import numpy as np
# Dades fictícies de vendes de 3 models de targetes gràfiques en 4 mesos
mesos = ["Gener", "Febrer", "Març", "Abril"]
gpu_models = ["RX 6400 Pulse", "AMD Radeon RX 7900 XTX", "RTX 3050 Dual OC 6 GB"]
vendes_gpu = np.array([
[120, 150, 170, 200], # RX 6400 Pulse
[90, 110, 140, 160], # AMD Radeon RX 7900 XTX
[100, 130, 120, 180] # RTX 3050 Dual OC 6 GB
])
# Crear el gràfic de línies utilitzant l'array de Numpy
# Marcadors i colors per cada línia
markers = ['o', 's', '^', 'D']
colors = ['blue', 'green', 'red', 'purple']
# Crear el gràfic de línies amb un bucle
plt.figure(figsize=(10, 6))
for i in range(len(gpu_models)):
plt.plot(mesos, vendes_gpu[i], marker=markers[i % len(markers)], label=gpu_models[i], linestyle='-', color=colors[i % len(colors)])
# Afegir títol i etiquetes
plt.title('Evolució de Vendes de Targetes Gràfiques (4 mesos)', fontsize=14)
plt.xlabel('Mesos', fontsize=12)
plt.ylabel('Vendes (Unitats)', fontsize=12)
plt.grid(True)
plt.legend(title="Models de GPU")
# Mostrar el gràfic
plt.tight_layout()
plt.savefig("plot.png")

Aquesta solució és correcta i escalable (si afegim mesos o productes funciona igual)

1. Crea un gràfic amb 3 línies que representin la evolució del seu nivell de glucosa a la sang en mg/L que tenen 3 pacients amb grip i amb 7 columnes, una per dia; guardat en numpy.

Pots inserir manualment les mostres o bé generar-les aleatòriament; l’important és que siguin dades versemblants de persones hospitalitzades.

Una possible manera de definir les dades és la següent:

# Dades de glucosa per a tres pacients en 7 dies.
days_x = np.arange(1, 8)
gl_patients_y = np.array([[110,130,120,145,140,131,120],
[125,135,151,143,132,120,111],
[120,125,112,103,108,111,105]])

Fes que vegi una llegenda i/o la descripció del gràfic i els seus eixos, així com diferenciar cada pacient per un color diferent.

Una presentació suggerida del gràfic:

Com els altres gràfics, es pot fer sense Numpy i aplicant el que hem après amb els diagrames de línies.

Aquests diagrames són molt adequats per mostrar les freqüències d’aparició de cada valor d’una variable.

Per exemple, els gols número de gols de cada jugadora o el número de d’aparicions de cada nucleòtid (A,C,G,T) en una cadena d’ADN.

import matplotlib.pyplot as plt
# Dades del gràfic
titol = "Gràfic de màximes golejadores del Barça (Lliga 2022-2023)."
etiq_y = "Núm gols"
etiq_x = "Jugadores"
llegenda_x = ["A.Oshoala", "S.Paralluelo", "A.Bonmati"]
valors_y = [21, 11, 10]
colors_y = ['tab:purple', 'tab:brown', 'tab:red']
# Creem el gràfic.
bar_container = plt.bar(llegenda_x, valors_y, color=colors_y)
plt.bar_label(bar_container, fmt='%.0f')
plt.ylabel(etiq_y)
plt.xlabel(etiq_x)
plt.title(titol)
#plt.legend(title='Jugadores')
# Només si vols usar Collab (ipynb)
#plt.show()
plt.savefig('players.png')

Amb Matplotlib i Numpy, també podem fer diagrames de barres agrupats; de manera semblant a com hem fet abans gràfics de diverses línies.

Per exemple, suposem que volem veure l’increment dels preus dels lloguers a ciutats de Catalunya.

Les posarem en un array de Numpy, on a l’eix Y hi haurà cada ciutat (Badalona a l’index 0, Barcelona a l’1…) i al de les X els anys (del 2021 al 2023, per exemple)

Les dades del gràfic les hem tret del dataset del preu mitjà dels lloguers als municipis de Catalunya (les hem preprocessat prèviament).

import numpy as np
import matplotlib.pyplot as plt
ciutats = ['Badalona', 'Barcelona', 'Cornella', 'L\'Hospitalet']
anys = ['2021', '2022', '2023']
preusLloguers23 = np.array([
[730.4,808.02,848.91], #Badalona
[918.84,1026.86,1136.4], #Barcelona
[695.5,723.23,790.39], #Cornella
[688.74,731.31,794.87] #L'Hospitalet
])
print(preusLloguers23)
# Generem el diagrama de barres per cada any
fig, ax = plt.subplots(figsize=(10, 6))
# Ample de les barres
bar_width = 0.2
# Posicions de les barres per cada any
x = np.arange(len(ciutats))
# Creem les barres per cada any
for i, any in enumerate(anys):
ax.bar(x + i * bar_width, data[:, i], width=bar_width, label=any)
# Configuració del gràfic
ax.set_xlabel('Ciutats')
ax.set_ylabel('Preu mitjà lloguer')
ax.set_title('Increment preu mitjà lloguer ciutats AMB')
ax.set_xticks(x + bar_width * (len(anys) - 1) / 2)
ax.set_xticklabels(ciutats)
ax.legend()
# Ajustar la visualització
plt.tight_layout()
plt.show()

Tingueu en compte que no sempre us vindran les dades “curades” i en ocasions tindreu, per exemple 100 observacions i les haureu de classificar d’alguna manera: per gènere, per edat…

Suposem que tenim en un array (o llista) els grups sanguinis de 40 pacients (A, O, AB, B) i volem fer un gràfic del número de pacients de cada grup.

Amb la funció de np.unique aconseguim aquesta agrupació.

Veiem-ho:

import numpy as np
import matplotlib.pyplot as plt
# Definir els grups sanguinis possibles
grups_sanguinis = ['A', 'B', 'AB', 'O']
# Generar aleatòriament els grups sanguinis per a 40 pacients
np.random.seed(0) # Fixem la llavor per a reproduir els resultats
mostres = np.random.choice(grups_sanguinis, 40)
print(mostres)
# Agrupar les mostres per tipus.
unique, counts = np.unique(mostres, return_counts=True)
data = dict(zip(unique, counts))
print(data)
# Diagrama de barres
plt.figure(figsize=(10, 5))
plt.bar(data.keys(), data.values(), color=['red', 'blue', 'green', 'purple'])
plt.title('Distribució de Grups Sanguinis (Diagrama de Barres)')
plt.xlabel('Grup Sanguini')
plt.ylabel('Nombre de Pacients')
plt.show()
# Diagrama de sectors
plt.figure(figsize=(8, 8))
plt.pie(data.values(), labels=data.keys(), autopct='%1.1f%%', colors=['red', 'blue', 'green', 'purple'])
plt.title('Distribució de Grups Sanguinis (Diagrama de Sectors)')
plt.show()

Les parts més interessants i novedoses del codi es troben al principi:

  1. Es generen les dades aleatòriament.
  2. Encara més important, aquestes línies que guarden els valors únics (unique) i el nombre d’ocurrències (counts)
  3. Al final ho guarden tot en un diccionari, per conveniència (però potser no caldria)
# Agrupar les mostres per tipus.
unique, counts = np.unique(mostres, return_counts=True)
data = dict(zip(unique, counts))

Ja sabem el més bàsic de generació de gràfics: la selecció de dades.

2. Crea un diagrama de barres que mostri la freqüència d’aparició dels 4 nucleòtids (A, C, G i T) d’una cadena d’ADN.

dna_seq = "ACGTACGATGCAAGCTAGCTAGCAAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGGTC"

Els heatmaps o mapes de calor són una alternativa molt útil als diagrames de barra compostos, per tal de veure totes les freqüències d’aparició de cada variable.

Generen una taula bidimensional amb els valors de 2 variables, on la llegenda de colors de les dades més altes les marca d’un color intens (pex vermell) i les més baixes d’un altre color oposat (pex blau).

Veiem-ho amb un exemple que ja vam veure a la secció de Numpy: el fitxer CSV de les temperatures de Barcelona dels últims 8 anys

Suposarem que ja hem carregat les temperatures dels últims 8 anys i generem el gràfic:

import numpy as np
import matplotlib.pyplot as plt
dades = [
[2016, 10.7, 11.3, 11.1, 13.6, 16.4, 21.6, 24.9, 24.5, 22.3, 17.1, 12.7, 11.5],
[2017, 7.9, 11.4, 13.3, 14.2, 18.3, 23.6, 24.2, 24.5, 19.5, 18.6, 12.5, 8.5],
[2018, 10.5, 6.7, 10.8, 14.7, 17.1, 21.5, 25.3, 25.8, 22.5, 17.0, 12.4, 11.1],
[2019, 8.1, 11.9, 13.5, 13.4, 15.6, 21.9, 25.4, 25.1, 21.8, 18.5, 11.9, 11.2],
[2020, 10.0, 12.8, 11.9, 14.3, 19.4, 20.1, 25.0, 25.5, 21.7, 16.4, 14.7, 9.3],
[2021, 7.7, 11.6, 12.1, 12.9, 17.3, 23.3, 24.8, 24.5, 23.0, 18.1, 11.3, 10.9],
[2022, 10.2, 11.8, 10.8, 14.1, 20.7, 24.7, 26.7, 27.2, 22.5, 20.7, 15.2, 12.6],
[2023, 9.2, 10.3, 14.1, 16.1, 18.1, 23.4, 25.5, 26.0, 23.2, 20.2, 14.8, 12.1]
]
data = np.array(dades)
# Separar les columnes per a les etiquetes dels anys i les temperatures
anys = data[:, 0]
temperatures = data[:, 1:]
# Crear el heatmap anotat
fig, ax = plt.subplots(figsize=(12, 8))
cax = ax.matshow(temperatures, cmap='coolwarm')
# Afegir la barra de color
cbar = fig.colorbar(cax, ax=ax, orientation='vertical')
cbar.set_label('Temperatura (°C)')
# Afegir anotacions
for (i, j), val in np.ndenumerate(temperatures):
ax.text(j, i, f'{val:.1f}', ha='center', va='center', color='black')
# Configurar les etiquetes
ax.set_xlabel('Mesos')
ax.set_ylabel('Anys')
ax.set_title('Heatmap de les temperatures mensuals a Barcelona (2016-2023)')
# Ajustar les etiquetes de l'eix X (mesos)
ax.set_xticks(np.arange(12))
ax.set_xticklabels(['Gen', 'Feb', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Oct', 'Nov', 'Des'])
# Ajustar les etiquetes de l'eix Y (anys)
ax.set_yticks(np.arange(data.shape[0]))
ax.set_yticklabels([str(int(year)) for year in anys])
plt.savefig("matplotlib7.png")

Però a la vida real no tindrem les dades tan curades, haurem de carregar-les d’un o més fonts i preprocessar-les.

En el nostre cas, necessitem descarregar-nos les dades si no les tenim al disc (connectar-se a una altra URL té un cost computacional i ambiental considerable).

Recordeu com podem aconseguir aquesta descàrrega i lectura de fitxers CSV que són en una URL externa: Fitxers

Un cop les tenim, carreguem les dades de les temperatures en un array, i filtrem únicament les 8 últimes.

Guardem els últims anys (2016 - 2023) en un vector 1D separat de les temperatures (si no, tindrem errors ja que els arrays han de ser homogenis).

La resta de passos, per a generar el gràfic, són els mateixos.

El codi final queda així:

import numpy as np
# Per a ipynb:
# !pip install nptyping
from nptyping import NDArray, Int, Float
import os.path
from urllib.request import urlretrieve
import matplotlib.pyplot as plt
url : str = 'https://opendata-ajuntament.barcelona.cat/data/dataset/73f09843-ab4e-4f13-81fb-b801ca371909/resource/0e3b6840-7dff-4731-a556-44fac28a7873/download/temperaturesbcndesde1780_2023.csv'
file : str = 'temperaturesbcn_2023.csv'
# Descarregar el fitxer CSV només si no existeix
if not os.path.isfile(file):
try:
urlretrieve(url, file)
print(f"Fitxer {file} descarregat correctament.")
except Exception as e:
print(f"No s'ha pogut descarregar el fitxer des de {url}: {str(e)}")
# Lectura del tot el fitxer CSV excepte la capçalera
data = np.loadtxt('temperaturesbcn_2023.csv', delimiter=',', skiprows=1)
# Seleccionem les últimes 8 files de temperatures (2016 - 2023)
# Separem la columna dels anys i la eliminem de l'array de temperatures.
temps_array = data[-8:,1:13]
anys_array = data[-8:,0]
# print(temps_array)
# print(anys_array)
# Crear el heatmap anotat
fig, ax = plt.subplots(figsize=(12, 8))
cax = ax.matshow(temps_array, cmap='coolwarm')
# Afegir la barra de color
cbar = fig.colorbar(cax, ax=ax, orientation='vertical')
cbar.set_label('Temperatura (°C)')
# Afegir anotacions i etiquetes
for (i, j), val in np.ndenumerate(temps_array):
ax.text(j, i, f'{val:.1f}', ha='center', va='center', color='black')
ax.set_xlabel('Mesos')
ax.set_ylabel('Anys')
ax.set_title('Heatmap de les temperatures mensuals a Barcelona (2016-2023)')
# Ajustar les etiquetes de l'eix X (mesos)
ax.set_xticks(np.arange(12))
ax.set_xticklabels(['Gen', 'Feb', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Oct', 'Nov', 'Des'])
# Ajustar les etiquetes de l'eix Y (anys)
ax.set_yticks(np.arange(len(anys_array))) # Canviar el número de ticks a 8 (les últimes 8 files)
ax.set_yticklabels([str(int(year)) for year in anys_array])
plt.savefig("matplotlib7.png")

El resultat del gràfic és el mateix, però el resolem amb un codi útil en més contextos i mantenible.

3. Crea un Heatmap a partir de l’exemple dels preus de lloguer, en vermell els preus més alts i en verd els més baixos.

El codi de partida és el següent:

import numpy as np
import matplotlib.pyplot as plt
ciutats = ['Badalona', 'Barcelona', 'Cornella', 'L\'Hospitalet']
anys = ['2021', '2022', '2023']
preusLloguers23 = np.array([
[730.4,808.02,848.91], #Badalona
[918.84,1026.86,1136.4], #Barcelona
[695.5,723.23,790.39], #Cornella
[688.74,731.31,794.87] #L'Hospitalet
])
print(preusLloguers23)

Els scatter plots són gràfics de punts en un pla (2D) o espai (3D). Podem pintar aquests punts de diversos colors o formes si usem subplots. Això als científics els va molt bé per a classificar a mostres d’individus o espècies per dues característiques que puguin tenir relació (per exemple, podem fer un mapa de punts de 2 colors: home i dona; tenint en compte la seva alçada i pes).

Però millor ho veiem amb un dataset d’exemple mostra les diverses espècies de la planta Iris. Aquest conjunt de dades, de 50 plantes de 3 espècies i 4 característiques importants, és un recurs típic per introduir-nos al data science.

import numpy as np
import matplotlib.pyplot as plt
import requests
import csv
import os
url_file : str = 'https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv'
local_file : str = 'iris.csv'
# Verificar si el fitxer ja existeix localment
if not os.path.exists(local_file):
# Descarregar el fitxer si no existeix
response = requests.get(url_file)
with open(local_file, 'wb') as f:
f.write(response.content)
# Llegir les dades del fitxer CSV amb NumPy
with open(local_file, 'r') as f:
reader = csv.reader(f)
headers = next(reader) # Saltar la fila de capçaleres
# Ho llegirà com array d'strings per evitar errors.
data = np.array([row for row in reader])
# Convertir les dades a arrays 1D de Numpy amb tipus ben definit.
sepal_length = data[:, 0].astype(float)
petal_length = data[:, 2].astype(float)
species = data[:, 4]
# Crear un subgràfic de punts per a cada espècie (n'hi ha 3)
plt.figure(figsize=(10, 6))
# Recorrem les espècies úniques i dibuixem els punts corresponents
for specie in np.unique(species):
# Seleccionem les longituds de pètals i sèpals per a l'espècie actual
petal_lengths = petal_length[species == specie]
sepal_lengths = sepal_length[species == specie]
# Dibuixem els punts per a aquesta espècie amb l'etiqueta corresponent
plt.scatter(petal_lengths, sepal_lengths, label=specie)
plt.xlabel('Longitud dels pètals')
plt.ylabel('Longitud de les sèpals')
plt.title('Distribució de longituds de pètals i sèpals per espècie (Iris Dataset)')
plt.legend()
plt.grid(True)
plt.savefig("matplotlib8.png")

Amb aquest gràfic, podem deduïr que la Iris Setosa sol tenir els pètals més petits respecte a les altres 2 espècies i la Virginica els més grans.

Histogrames i corbes de distribució normal.

Section titled “Histogrames i corbes de distribució normal.”

Una de les tasques més comuns en estadística (tant descriptiva = dades, com inferencial = probabilitats) és generar gràfics per veure quina distribució presenten les dades un cop sabem la freqüència de cada ocurrència d’una variable; i gràcies a Numpy i Matplotlib podem generar aquest gràfic molt fàcilment.

Una de les distribucions teòriques més utilitzada a la pràctica és la distribució normal, també anomenada distribució gaussiana en honor al matemàtic Carl Friedrich Gauss.

Ara veurem la potència que té Numpy per a generar una col·lecció de dades que segueixen la distribució Normal i Matplotlib per a dibuixar tant un histograma per veure la distribució i una línia per veure com s’assembla la distribució que tenim respecte la Normal.

Provem aquest exemple fictici del nivell de colesterol a la sang de 300 pacients.

import numpy as np
import matplotlib.pyplot as plt
# Paràmetres per a la distribució normal
mean = 180 # mitjana del colesterol (mg/dL)
std_dev = 25 # desviació estàndard (mg/dL)
n_samples = 300 # nombre de mostres
# Generar dades aleatòries amb una distribució normal
cholesterol_levels = np.random.normal(mean, std_dev, n_samples)
# Crear l'histograma
plt.hist(cholesterol_levels, bins=20, density=True, alpha=0.6, color='g', edgecolor='black')
# Crear la corba de distribució normal
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 100)
p = np.exp(-0.5*((x-mean)/std_dev)**2) / (std_dev * np.sqrt(2 * np.pi))
plt.plot(x, p, 'k', linewidth=2)
# Afegir títol i etiquetes
plt.title('Distribució dels Nivells de Colesterol')
plt.xlabel('Nivells de Colesterol (mg/dL)')
plt.ylabel('Freqüència')
# Afegir línia vertical a la mitjana
plt.axvline(mean, color='b', linestyle='dashed', linewidth=2, label='Mitjana')
# Afegir línies verticals als intervals de confiança (±1 desviació estàndard)
plt.axvline(mean - std_dev, color='r', linestyle='dotted', linewidth=2, label='-1 Desviació estàndard')
plt.axvline(mean + std_dev, color='r', linestyle='dotted', linewidth=2, label='+1 Desviació estàndard')
plt.legend()
plt.savefig("matplotlib9.png")


Exercicis. Gràfics anàlisi de la qualitat de vins.

Section titled “Exercicis. Gràfics anàlisi de la qualitat de vins.”

El dataset de qualitat del vi (Wine Quality Dataset) és un conjunt de dades molt utilitzat en l’anàlisi de dades i el machine learning.

Conté informació sobre les característiques físiques i químiques dels vins, així com les puntuacions de qualitat que han rebut en tests de tast.

Pots trobar el resum del dataset a la seva web oficial: https://archive.ics.uci.edu/dataset/186/wine+quality

De totes les columnes, les que ens interessa guardar per a les gràfiques que farem són:

9pH (els vins són àcids, el seu PH pot oscilar entre 2.5 i 4.5)
11alcohol (en %, sol oscilar entre 9 i 15)
12quality (puntuació entre 0 i 10)

Primer, creem un mòdul d’utilitat wineutils.py per llegir (i descarregar només si cal) els fitxers:

import numpy as np
import urllib3
import os
def get_file(url, file):
http = urllib3.PoolManager()
if not os.path.isfile(file):
response = http.request("GET", url)
# Comprovar si la petició ha estat exitosa
if response.status == 200:
print(f"Descarregant el fitxer: {file}")
with open(file, "wb") as f:
f.write(response.data)
else:
print(f"Error en descarregar el fitxer: {response.status}")
return file
def read_csv(local_file):
data = np.genfromtxt(local_file, delimiter=';', skip_header=1)
return data

Ens han demanat els següents gràfics per tal d’analitzar la qualitat dels vins que tenim:

4. Crear un gràfic de dispersió (scatter plot) que mostri la relació entre dues característiques del vi, per exemple, el contingut d’alcohol i la puntuació de qualitat. Pots provar qualsevol altre mesura, com el PH.

5. Crear un histograma que mostri la distribució de la puntuació de qualitat dels vins i afegeix la corba de distribució normal.

A continuació veurás com servir els gràfics que has generat via web.

Clona el projecte https://gitlab.com/xtec/python/matplotlib

Terminal window
> git clone https://gitlab.com/xtec/python/matplotlib

Obre el projecte amb PyCharm:

Terminal window
webstorm matplotlib

Ara, prova de mostrar algún dels teus gràfics a la web. 📈📊


El contingut d'aquest lloc web té llicència CC BY-NC-ND 4.0.

©2022-2025 xtec.dev