10.6. Exemple pràctic de tractament de dades d’una font espanyola
Les dades provinents de fonts espanyoles s’acostumen a trobar en fitxers .csv que no estan delimitats per comes, sinó per punts i comes. Veurem un exemple que tracta moltes de les instruccions que hem anat veient al llarg del curs i que treballa amb dades d’una font espanyola.
Per dur a terme aquest exemple, agafarem les dades d’un repositori públic, en aquest cas de l’Ajuntament de Madrid. Hem triat les dades d’accidents de trànsit on hi ha implicades bicicletes. Aquestes dades estan disponibles en aquest enllaç.
Per fer aquest exemple, agafem les dades de 2021, que té disponibles tots els mesos.
El primer que haurem de fer és un petit canvi en el fitxer. Per defecte, a Espanya els fitxers .csv venen delimitats per punts i coma, però l’estàndard és que sigui una coma. Això és així perquè a Espanya el separador de decimals és una coma, mentre que als països anglosaxons és un punt. Per poder diferenciar la coma decimal de la coma separadora de camps de dades, a Espanya s’usa el ; com a separador de dades.
Així que el primer que farem serà obrir el fitxer descarregat amb un editor de fulls de càlcul i tornar-lo a desar com a text separat per tabuladors.

Font: elaboració pròpia.
Podem aprofitar que obrim el fitxer per fer-nos una idea de com estan distribuïdes les dades i de les seves principals característiques.
Ara ja podem pujar el fitxer a la Mediateca de CodeLab.
Per poder-ho usar en el nostre programa, l’haurem d’obrir amb la instrucció loadTable. Farem com amb les imatges, crear una variable i, dins de la funció preload(), carregar les dades.
let bicis; function preload() { bicis = loadTable("URL", "tsv", "header"); }
A loadTable li passem tres paràmetres: URL, que és l’adreça del nostre fitxer al servidor (ens l’indica la Mediateca de CodeLab); «tsv» diu a loadTable que el fitxer està delimitat per tabuladors, i «header» que la primera fila de dades és de capçalera.
Ja tenim el fitxer i ara hi treballarem. Representarem el nombre d’accidents per mesos, així que el que farem és recórrer totes les dades comptant el nombre d’accidents de cada mes.
Per desar el nombre d’accidents de cada mes, crearem un array de dotze posicions:
let meses = [0,0,0,0,0,0,0,0,0,0,0,0];
Per obtenir aquestes dades, recorrerem tota la taula de dades mirant la data, i ens quedarem amb el mes. Aquí ens servirà saber com estan desades les dades. Quan hem obert el fitxer, hem vist que totes les dates tenen el format dd/mm/aaaa afegint un zero a l’esquerra quan cal. Per tant, de la data ens quedarem amb els valors de mm, situats a les posicions quarta i cinquena de la data.
let bicis; let meses = [0,0,0,0,0,0,0,0,0,0,0,0]; function preload() { bicis = loadTable("https://codelab.uoc.edu/filemanager/source_repo/ccasadom/AccidentesBicicletas_2021-TAB.txt", "tsv", "header"); }
Vegem com queda ara el nostre programa
A la funció setup() creem el canvas i cridem a la funció preparacion() que desarà a la taula mesos quants accidents hi ha cada mes. Quatre anotacions:
- Hem usat dos mètodes que treballen amb les dades getRowCount(), que ens diu quantes dades hi ha en bicis, i get(i,j), que recupera la dada situada a la fila i, columna j. Recordeu que sempre hem de començar per 0. A més, com que hem indicat que el fitxer té capçalera, p5.js directament ignora la fila de la capçalera.
- Usem el mètode slice(x,y), que extreu de la cadena de text els valors que van des de la posició x fins a la posició y-1.
- Usem la funció parseInt(t), que converteix el text t en un nombre (sempre que t estigui compost de dígits).
- Com que la taula comença per zero i els mesos per 1, resta 1 al número de mes per desar les dades a la taula.
Si afegim la instrucció console.log(mesos); després de cridar a la funció preparacion(), veurem a la consola la taula amb les dades obtingudes:

Font: elaboració pròpia.
El pas següent és visualitzar les dades. Per a això, usarem un simple gràfic de barres.
El primer pas consistirà a saber quin és el valor màxim dels obtinguts. Per què? Perquè així podem ajustar bé l’alçària de les barres. Si no sabem quina és l’alçària màxima que hem de representar, el gràfic podria quedar molt petit o massa gran.
Crearem una funció que ens calculi el valor màxim de tots els elements d’un array:
function maxArray(tabla){ let max = tabla[0]; for (let i = 1; i < tabla.lenght; i++) { if (tabla[i]>max) { max = tabla[i]; } } return max; }
Ara ja tenim les dades que volem representar i un valor màxim per determinar el valor de les barres. Només queda representar les dades. I dibuixar és cosa de la funció draw().
function draw() { background(100); fill(255); for (var i = 0; i < 12; i++) { rect(30+(i*46), 380-map(mesos[i],0,max,0,100), 30, map(mesos[i],0,max,0,100)); } }
El que fem és, per a cada dia de la setmana, dibuixar un rectangle. El for ens serveix per pintar els set dies. I el dibuix es fa amb una funció rect().
Dibuixar les barres és una mica complicat, així que anirem veient tots els paràmetres de la funció rect() un a un. Primer, no obstant això, recordem com és la funció rect():
rect(x, y, w, h) x Nombre: coordenada x del rectangle. y Nombre: coordenada y del rectangle. w Nombre: amplària del rectangle. h Nombre: alçària del rectangle.
Recordem que comencem a pintar els rectangles a partir del seu vèrtex superior esquerre. Bé, vegem ara els diferents paràmetres. La x:
30+(i*46)
El que estem fent és que la primera barra la posarem a 30 píxels de l’esquerra del canvas. La segona, 46 píxels més enllà, i així successivament. Com que les barres les farem de 30 píxels, tindrem una separació de 16 píxels entre barra i barra. D’aquesta manera, els dotze mesos queden ben presentats.
Ara la y.
380-map(mesos[i],0,max,0,100)
Això és més complicat. Les barres començaran (visualment) als 380 píxels. I tindran una alçària màxima de 100 píxels. Primer, el que hem de fer és convertir el nombre d’accidents, que estarà entre 0 i max (recordeu d’on ve aquest valor?), en un valor entre 0 i 100. Això ho fem amb la funció map(). Amb la funció map() obtenim l’alçària que tindrà la barra. Per decidir en quina posició y cal començar, restem a la posició final (380) l’alçària de la barra. I ja sabem on hem de començar a pintar.
Ara ens falta determinar l’amplària:
30
i l’alçària:
map(mesos[i],0,max,0,100)
Que ja havíem usat abans. El programa queda així:
let bicis; let mesos = [0,0,0,0,0,0,0,0,0,0,0,0]; let max; function preload() { bicis = loadTable("https://codelab.uoc.edu/filemanager/source_repo/ccasadom/AccidentesBicicletas_2021-TAB.txt", "tsv", "header"); } function setup() { createCanvas(600, 400); noStroke(); preparacion(); max = maxArray(mesos); } function draw() { background(100); fill(255); for (var i = 0; i < 12; i++) { rect(30+(i*46), 380-map(meses[i],0,max,0,100), 30, map(mesos[i],0,max,0,100)); } } function preparacio(){ for (let i = 0; i < bicis.getRowCount(); i++) { let data = bicis.get(i,1); let mes = fecha.slice(3,5); meses[parseInt(mes)-1]++; } } function maxArray(tabla){ let max = tabla[0]; for (let i = 1; i < tabla.lenght; i++) { if (tabla[i]>max) { max = tabla[i]; } } return max; }
Fins aquí hem vist com recuperar les dades i treballar-hi després.
No obstant això, és veritat que falta informació. Seria recomanable almenys indicar a quin mes representa cada barra i el nombre total d’accidents.
Per a això, farem que quan el cursor passi per sobre d’una barra, es pinti de color vermell i s’escrigui el dia de la setmana i el nombre d’accidents a sobre, com es pot veure en aquesta captura:

Font: elaboració pròpia.
Els canvis que hem de fer afecten les funcions setup() i draw(). A més, a l’inici hem afegit una variable nova:
let nomMes =["Gener","Febrer","Març","Abril","Maig","Juny","Juliol","Agost","Setembre","Octubre","Novembre","Desembre"];
Aquesta variable és una taula en la qual desarem els noms dels mesos, per usar-los després en la creació del text.
function setup() { createCanvas(600, 400); noStroke(); preparacion(); max = maxArray(mesos); textFont("Arial"); textSize(24); }
A la funció setup() hem afegit les dues instruccions que determinen el tipus de lletra i la mida.
En la funció draw() hem afegit un if perquè, quan el ratolí estigui sobre una barra, s’escrigui el nom del mes i el nombre d’accidents que hi ha hagut.
Amb aquest codi, podem baixar-nos un altre any de dades (sempre que mantingui la mateixa estructura) i representar-lo.
function draw() { background(100); for (var i = 0; i < 12; i++) { fill(255); rect(30+(i*46), 380-map(mesos[i],0,max,0,100), 30, map(mesos[i],0,max,0,100)); if ((mouseX > 30+(i*46)) && (mouseX < 30+(i*46)+30)) { fill(255,0,0); rect(30+(i*46), 380-map(mesos[i],0,max,0,100), 30, map(mesos[i],0,max,0,100)); fill("#CECEF6"); text(nomMes[i] + ": "+mesos[i]+" accidents.", 40, 70); } } }