2012-06-29 9 views
14

Molto spesso desidero creare un grafico a barre di conteggi. Se i conteggi sono bassi, spesso ottengo posizioni di tick maggiori e/o secondarie che non sono numeri interi. Come posso evitare questo? Non ha senso avere un segno di spunta a 1.5 quando i dati sono importanti.Python matplotlib limitano le posizioni dei segni di spunta di numero intero

Questo è il mio primo tentativo:

import pylab 
pylab.figure() 
ax = pylab.subplot(2, 2, 1) 
pylab.bar(range(1,4), range(1,4), align='center') 
major_tick_locs = ax.yaxis.get_majorticklocs() 
if len(major_tick_locs) < 2 or major_tick_locs[1] - major_tick_locs[0] < 1: 
    ax.yaxis.set_major_locator(pylab.MultipleLocator(1)) 
minor_tick_locs = ax.yaxis.get_minorticklocs() 
if len(minor_tick_locs) < 2 or minor_tick_locs[1] - minor_tick_locs[0] < 1: 
    ax.yaxis.set_minor_locator(pylab.MultipleLocator(1)) 

che funziona bene quando i conti sono piccole, ma quando sono grandi, ottengo molte molte zecche minori:

import pylab 
ax = pylab.subplot(2, 2, 2) 
pylab.bar(range(1,4), range(100,400,100), align='center') 
major_tick_locs = ax.yaxis.get_majorticklocs() 
if len(major_tick_locs) < 2 or major_tick_locs[1] - major_tick_locs[0] < 1: 
    ax.yaxis.set_major_locator(pylab.MultipleLocator(1)) 
minor_tick_locs = ax.yaxis.get_minorticklocs() 
if len(minor_tick_locs) < 2 or minor_tick_locs[1] - minor_tick_locs[0] < 1: 
    ax.yaxis.set_minor_locator(pylab.MultipleLocator(1)) 

Come posso ottenere il comportamento desiderato dal primo esempio con piccoli conteggi evitando ciò che accade nel secondo?

+0

Questo è contrassegnato erroneamente come duplicato. È stato chiesto prima dell'altra domanda. L'altra domanda dovrebbe essere quella contrassegnata come duplicata. – John

risposta

24

È possibile utilizzare il metodo MaxNLocator, in questo modo:

from pylab import MaxNLocator 

    ya = axes.get_yaxis() 
    ya.set_major_locator(MaxNLocator(integer=True)) 
+1

Credo che 'pylab.MaxNLocator()' è una notazione migliore. – FooBar

+2

o se non stai importando pylab, 'matplotlib.ticker.MaxNLocator()'. (da [questa risposta] (http://stackoverflow.com/a/27496811/2452770)) –

0

Penso che sia possibile ignorare le tacche secondarie. Ho intenzione di dare a questo un andare e vedere se si alza in tutti i casi di utilizzo:

def ticks_restrict_to_integer(axis): 
    """Restrict the ticks on the given axis to be at least integer, 
    that is no half ticks at 1.5 for example. 
    """ 
    from matplotlib.ticker import MultipleLocator 
    major_tick_locs = axis.get_majorticklocs() 
    if len(major_tick_locs) < 2 or major_tick_locs[1] - major_tick_locs[0] < 1: 
     axis.set_major_locator(MultipleLocator(1)) 

def _test_restrict_to_integer(): 
    pylab.figure() 
    ax = pylab.subplot(1, 2, 1) 
    pylab.bar(range(1,4), range(1,4), align='center') 
    ticks_restrict_to_integer(ax.xaxis) 
    ticks_restrict_to_integer(ax.yaxis) 

    ax = pylab.subplot(1, 2, 2) 
    pylab.bar(range(1,4), range(100,400,100), align='center') 
    ticks_restrict_to_integer(ax.xaxis) 
    ticks_restrict_to_integer(ax.yaxis) 

_test_restrict_to_integer() 
pylab.show() 
2
pylab.bar(range(1,4), range(1,4), align='center') 

e

xticks(range(1,40),range(1,40)) 

ha funzionato nel mio codice. Basta usare il parametro opzionale align e xticks fa la magia.

+0

Questo metodo non offre troppe zecche per i grandi intervalli? – John

Problemi correlati