2016-02-15 7 views
8

Ho un grafico di log-log in cui l'intervallo va da 10^-3 a 10^+3. Desidero che i valori ≥10^0 abbiano un segno + nell'esponente analogo a come i valori <10^0 hanno un segno - nell'esponente. C'è un modo semplice per farlo in matplotlib?Aggiunta + segno all'esponente negli assi matplotlib

Ho esaminato FuncFormatter ma sembra troppo complesso per raggiungere questo obiettivo e inoltre non riuscivo a farlo funzionare.

+0

Vuoi dire che vorresti formattare le annotazioni per i segni di spunta sugli assi xe così? – tokamak

+0

@tokamak - Per il momento in realtà interessa solo l'asse y ma sarebbe bello impostare entrambi gli assi singolarmente – nluigi

+0

Guardando il codice che genera i segni di spunta https://github.com/matplotlib/matplotlib/blob/ 7d1a7c2e4637efba239ad3b984928c0175d45f98/lib/matplotlib/ticker.py # L803 sembra che non ci sia un modo ovvio per cambiarlo da solo. Immagino che un modo non ottimale sarebbe semplicemente creare una versione modificata di quella linea mutevole 823. –

risposta

5

Si può fare questo con un FuncFormatter dal modulo matplotlib.ticker. È necessaria una condizione per stabilire se il valore del segno di spunta è maggiore o minore di 1. Quindi, se log10(tick value) è >0, quindi aggiungere il segno + nella stringa dell'etichetta, in caso contrario, otterrà automaticamente il segno meno.

import matplotlib.pyplot as plt 
import matplotlib.ticker as ticker 
import numpy as np 

# sample data 
x = y = np.logspace(-3,3) 

# create a figure 
fig,ax = plt.subplots(1) 

# plot sample data 
ax.loglog(x,y) 

# this is the function the FuncFormatter will use 
def mylogfmt(x,pos): 
    logx = np.log10(x) # to get the exponent 
    if logx < 0: 
     # negative sign is added automatically 
     return u"$10^{{{:.0f}}}$".format(logx) 
    else: 
     # we need to explicitly add the positive sign 
     return u"$10^{{+{:.0f}}}$".format(logx) 

# Define the formatter 
formatter = ticker.FuncFormatter(mylogfmt) 

# Set the major_formatter on x and/or y axes here 
ax.xaxis.set_major_formatter(formatter) 
ax.yaxis.set_major_formatter(formatter) 

plt.show() 

enter image description here

Qualche spiegazione della stringa di formato:

"$10^{{+{:.0f}}}$".format(logx) 

le doppie parentesi {{ e }} sono passati a LaTeX, a significare tutto ciò che in essi dovrebbero essere sollevate come esponente. Abbiamo bisogno di doppie parentesi, perché le singole parentesi vengono utilizzate da python per contenere la stringa di formato, in questo caso {:.0f}. Per ulteriori spiegazioni sulle specifiche del formato, vedere docs here, ma TL; DR per il tuo caso è la formattazione di un float con una precisione di 0 posizioni decimali (ovvero la stampa essenzialmente come un intero); l'esponente è un float in questo caso perché np.log10 restituisce un float. (si potrebbe in alternativa convertire l'output di np.log10 in un file int e quindi formattare la stringa come int - solo una questione di preferenza che si preferisce).

+0

Ok, io vado con questo ... puoi spiegare il formato di' {{: .0f}} 'sto indovinando il vengono usate parentesi eccessive per uscire, ma cosa fa esattamente ': .0f'? – nluigi

0

Spero che questo è quello che cercavi:

def fmt(y, pos): 
    a, b = '{:.2e}'.format(y).split('e') 
    b = int(b) 
    if b >= 0: 
     format_example = r'$10^{+{}}$'.format(b) 
    else: 
     format_example = r'$10^{{}}$'.format(b) 
    return 

Quindi utilizzare FuncFormatter, per esempio per una barra colori: plt.colorbar(name_of_plot,ticks=list_with_tick_locations, format = ticker.FuncFormatter(fmt)). Penso che devi importare import matplotlib.ticker as ticker.

saluti

Problemi correlati