HOWTO · Matplotlib

Traccia assi logaritmici in Matplotlib

Traccia assi logaritmici in Matplotlib con set_yscale(), semilogy() o loglog().

In questa pagina

Usa set_xscale() o set_yscale() per scegliere separatamente la scala di ciascun asse. Per applicare una scala logaritmica a entrambi gli assi, usa loglog(). Le funzioni ausiliarie semilogx() e semilogy() applicano rispettivamente una scala logaritmica all’asse x o all’asse y. Un asse logaritmico dispone i suoi segni di graduazione per potenze di dieci, così i dati che coprono più ordini di grandezza restano leggibili invece di addensarsi nella decade più bassa di un asse lineare.
Tutti gli esempi di codice seguenti sono stati eseguiti correttamente.

Funzioni set_xscale() o set_yscale()

Chiama set_xscale("log") per impostare la scala logaritmica sull’asse x, set_yscale("log") per impostarla sull’asse y, oppure entrambe per applicarla a tutti e due gli assi. Poiché le due chiamate sono indipendenti, puoi convertire esattamente un asse e lasciare l’altro lineare.

Per rendere logaritmico solo l’asse x, traccia i dati come al solito e poi chiama set_xscale("log") sugli assi:

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 5, 20, 80]

fig, ax = plt.subplots()
ax.plot(x, y, marker="o")
ax.set_xscale("log")
ax.set_xlabel("x")
ax.set_ylabel("y")
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

Il risultato stampato conferma che è cambiato solo l’asse x: x-axis: log, y-axis: linear. I segni di decade a 1, 10, 100 e 1000 sono equidistanti, anche se i valori stessi crescono di un fattore dieci.

Grafico a linee con un asse x logaritmico e un asse y lineare, creato con set_xscale

Per rendere logaritmico solo l’asse y, chiama invece set_yscale("log") e lascia invariato l’asse x:

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 5, 20, 80]

fig, ax = plt.subplots()
ax.plot(x, y, marker="o")
ax.set_yscale("log")
ax.set_xlabel("x")
ax.set_ylabel("y")
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

Questa volta l’output è x-axis: linear, y-axis: log, ed è l’asse y a portare i segni di decade equidistanti.

Grafico a linee con un asse x lineare e un asse y logaritmico, creato con set_yscale

L’interfaccia state-machine di pyplot offre la stessa modifica tramite le funzioni di primo livello plt.xscale() e plt.yscale(), che agiscono sugli assi correnti. La variante con yscale() dello stesso grafico è la seguente:

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 5, 20, 80]

plt.plot(x, y, marker="o")
plt.yscale("log")
plt.xlabel("x")
plt.ylabel("y")
ax = plt.gca()
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close()

Il risultato è lo stesso asse y logaritmico; i metodi dell’oggetto axes sono di solito più chiari nei programmi che mantengono un riferimento ax esplicito, perché gli assi di destinazione sono indicati nella chiamata invece di essere impliciti nella figura corrente.

Grafico a linee con un asse y logaritmico, creato con la funzione yscale di pyplot

Questo esempio completo traccia dati numerici positivi e imposta entrambi gli assi su una scala logaritmica.

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 5, 20, 80]

fig, ax = plt.subplots()
ax.plot(x, y, marker="o")
ax.set_xscale("log")
ax.set_yscale("log")
ax.set_xlabel("x")
ax.set_ylabel("y")
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

Ora l’output riporta x-axis: log, y-axis: log, e rapporti uguali occupano distanze uguali su entrambi gli assi.

Grafico a linee con scale logaritmiche su entrambi gli assi, creato con set_xscale e set_yscale

Una scala standard log rappresenta valori positivi. Se i dati includono valori con segno, usa symlog per l’asse interessato, ad esempio ax.set_yscale("symlog"); permette di visualizzare valori sia positivi sia negativi. L’ultima sezione riprende questo caso con un esempio verificato.

Funzioni semilogx() o semilogy()

Usa semilogx() quando vuoi una scala logaritmica sull’asse x e una lineare sull’asse y. Usa semilogy() per ottenere una scala logaritmica sull’asse y e lineare sull’asse x. Entrambe le funzioni accettano i dati x e y come argomenti, quindi la scala scelta è indicata esplicitamente nella chiamata di plotting. Se vuoi una scala logaritmica su entrambi gli assi, usa loglog() oppure combina semilogx() e semilogy() sugli stessi assi.

La chiamata semilogx() seguente traccia i dati e imposta l’asse x logaritmico in un unico passaggio:

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 5, 20, 80]

fig, ax = plt.subplots()
ax.semilogx(x, y, marker="o", label="logarithmic x")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.legend()
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

La funzione restituisce la linea tracciata e gli assi riportano poi x-axis: log, y-axis: linear, esattamente come con la chiamata esplicita set_xscale("log") della prima sezione.

Grafico a linee con un asse x logaritmico e un asse y lineare, creato con semilogx

Combinando le due funzioni sugli stessi assi si ottiene una scala logaritmica su entrambi gli assi. Tieni presente che una scala appartiene agli assi, non a una singola linea tracciata: una volta che semilogy() imposta l’asse y, quella scala si applica a tutte le serie contenute negli assi, compresa quella disegnata prima da semilogx().

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 5, 20, 80]
y2 = [3, 8, 30, 120]

fig, ax = plt.subplots()
ax.semilogx(x, y, marker="o", label="first series")
ax.semilogy(x, y2, marker="s", label="second series")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.legend()
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

Entrambe le serie finiscono su assi x e y logaritmici, e l’output conferma lo stato finale: x-axis: log, y-axis: log.

Due serie di linee che condividono assi x e y logaritmici, create combinando semilogx e semilogy

Funzione loglog()

Usa loglog() quando vuoi applicare una scala logaritmica a entrambi gli assi. La funzione traccia i dati x e y forniti e imposta entrambi gli assi sulla scala logaritmica standard. Ecco un esempio completo con valori numerici positivi:

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 5, 20, 80]

fig, ax = plt.subplots()
ax.loglog(x, y, marker="o")
ax.set_xlabel("x")
ax.set_ylabel("y")
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

Il risultato renderizzato corrisponde alla combinazione set_xscale("log") più set_yscale("log") della prima sezione; loglog() integra semplicemente la scelta della scala nella chiamata di plotting stessa.

Grafico a linee con scale logaritmiche su entrambi gli assi, creato con loglog

Valori non positivi e nomi di scala non validi

Due cose sorprendono regolarmente chi usa gli assi logaritmici, ed è bene conoscerle entrambe prima di fare il debug di un grafico dall’aspetto sbagliato. Primo, il nome della scala viene convalidato immediatamente: un errore di battitura come ax.set_yscale("logg") solleva ValueError: 'logg' is not a valid value for scale. Did you mean one of: 'log', 'logit', 'symlog'? (messaggio catturato alla lettera su Matplotlib 3.11). L’errore elenca i valori accettati, così un refuso fallisce subito invece di produrre silenziosamente un asse lineare.

Secondo, una scala logaritmica non può rappresentare lo zero né i valori negativi, e questo caso non solleva alcun errore. Matplotlib scarta silenziosamente i punti non positivi: vengono mascherati fuori dal disegno, i segmenti di linea che li attraverserebbero scompaiono, e i limiti dell’asse coprono solo i valori positivi. L’esempio seguente traccia y = [2, 0, -5, 80] su un asse y logaritmico:

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 0, -5, 80]

fig, ax = plt.subplots()
ax.plot(x, y, marker="o")
ax.set_yscale("log")
ax.set_xlabel("x")
ax.set_ylabel("y")
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

La chiamata si completa normalmente e riporta y-axis: log, ma possono apparire solo i punti a y = 2 e y = 80; nell’esecuzione verificata, i limiti risultanti dell’asse y andavano approssimativamente da 1,66 a 96,2, coprendo solo i dati positivi. Se una serie sembra perdere punti dopo aver impostato un asse su log, controlla i dati alla ricerca di zeri e valori negativi prima di sospettare del codice di plotting.

Quando i dati contengono davvero valori con segno, la scala symlog (logaritmo simmetrico) è l’alternativa appropriata: applica una scala logaritmica lontano dallo zero e una scala lineare in una piccola regione intorno allo zero, così ogni punto resta visibile.

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 0, -5, 80]

fig, ax = plt.subplots()
ax.plot(x, y, marker="o")
ax.set_yscale("symlog")
ax.set_xlabel("x")
ax.set_ylabel("y")
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

Tutti e quattro i punti, inclusi 0 e -5, vengono tracciati sull’asse y symlog. Usala ogni volta che il segno dei valori porta informazione; mantieni la semplice scala log per i dati positivi per natura, come conteggi, dimensioni e misure fisiche.