web-dev-qa-db-fra.com

Changer la "fréquence de ticks" sur les axes x ou y dans matplotlib?

J'essaie de corriger la manière dont python trace mes données.

Dire

x = [0,5,9,10,15]

et

y = [0,1,2,3,4]

Alors je ferais:

matplotlib.pyplot.plot(x,y)
matplotlib.pyplot.show()

et les graduations de l'axe des abscisses sont tracées par intervalles de 5. Existe-t-il un moyen de faire apparaître des intervalles de 1?

382
Dax Feliz

Vous pouvez définir explicitement l'endroit où vous souhaitez cocher les cases avec plt.xticks:

plt.xticks(np.arange(min(x), max(x)+1, 1.0))

Par exemple,

import numpy as np
import matplotlib.pyplot as plt

x = [0,5,9,10,15]
y = [0,1,2,3,4]
plt.plot(x,y)
plt.xticks(np.arange(min(x), max(x)+1, 1.0))
plt.show()

(np.arange a été utilisé plutôt que la fonction range de Python au cas où min(x) et max(x) seraient des flottants au lieu de ints.)


La fonction plt.plot (ou ax.plot) définit automatiquement les limites par défaut de x et y. Si vous souhaitez conserver ces limites et modifier simplement la taille des graduations, vous pouvez utiliser ax.get_xlim() pour découvrir les limites déjà définies par Matplotlib.

start, end = ax.get_xlim()
ax.xaxis.set_ticks(np.arange(start, end, stepsize))

Le formateur de ticks par défaut devrait faire un travail décent en arrondissant les valeurs de ticks à un nombre raisonnable de chiffres significatifs. Toutefois, si vous souhaitez mieux contrôler le format, vous pouvez définir votre propre formateur. Par exemple,

ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1f'))

Voici un exemple exécutable:

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

x = [0,5,9,10,15]
y = [0,1,2,3,4]
fig, ax = plt.subplots()
ax.plot(x,y)
start, end = ax.get_xlim()
ax.xaxis.set_ticks(np.arange(start, end, 0.712123))
ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1f'))
plt.show()
466
unutbu

Une autre approche consiste à définir le localisateur d’axe:

import matplotlib.ticker as plticker

loc = plticker.MultipleLocator(base=1.0) # this locator puts ticks at regular intervals
ax.xaxis.set_major_locator(loc)

Il existe plusieurs types de localisateurs en fonction de vos besoins.

Voici un exemple complet:

import matplotlib.pyplot as plt
import matplotlib.ticker as plticker

x = [0,5,9,10,15]
y = [0,1,2,3,4]
fig, ax = plt.subplots()
ax.plot(x,y)
loc = plticker.MultipleLocator(base=1.0) # this locator puts ticks at regular intervals
ax.xaxis.set_major_locator(loc)
plt.show()
168
robochat

J'aime cette solution (tirée du Matplotlib Plotting Cookbook ):

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

x = [0,5,9,10,15]
y = [0,1,2,3,4]

tick_spacing = 1

fig, ax = plt.subplots(1,1)
ax.plot(x,y)
ax.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))
plt.show()

Cette solution vous donne un contrôle explicite de l’espacement des ticks via le numéro attribué à ticker.MultipleLocater(), permet la détermination automatique des limites et est facile à lire ultérieurement.

98
jthomas

Si quelqu'un est intéressé par une ligne unique, il suffit d'obtenir les ticks actuels et de l'utiliser pour définir les nouveaux ticks en échantillonnant tous les autres ticks.

ax.set_xticks(ax.get_xticks()[::2])
69
glopes

Ceci est un peu hacky, mais de loin l'exemple le plus propre/le plus facile à comprendre que j'ai trouvé pour le faire. Cela provient d'une réponse sur SO ici:

Le moyen le plus propre de masquer chaque énième étiquette de coche dans la barre de couleurs matplotlib?

for label in ax.get_xticklabels()[::2]:
    label.set_visible(False)

Ensuite, vous pouvez faire une boucle sur les étiquettes pour les rendre visibles ou non en fonction de la densité souhaitée.

edit: notez que parfois matplotlib définit des étiquettes == '', il peut donc sembler qu’une étiquette n’est pas présente, alors qu’elle n’affiche rien. Pour vous assurer que vous parcourez les étiquettes visibles, vous pouvez essayer:

visible_labels = [lab for lab in ax.get_xticklabels() if lab.get_visible() is True and lab.get_text() != '']
plt.setp(visible_labels[::2], visible=False)
27
choldgraf

C’est un vieux sujet, mais j’ai trébuché dessus de temps en temps et j’ai créé cette fonction. C'est très pratique:

import matplotlib.pyplot as pp
import numpy as np

def resadjust(ax, xres=None, yres=None):
    """
    Send in an axis and I fix the resolution as desired.
    """

    if xres:
        start, stop = ax.get_xlim()
        ticks = np.arange(start, stop + xres, xres)
        ax.set_xticks(ticks)
    if yres:
        start, stop = ax.get_ylim()
        ticks = np.arange(start, stop + yres, yres)
        ax.set_yticks(ticks)

Un inconvénient à contrôler les ticks comme ceci est que l’on n’apprécie plus la mise à jour interactive automagique de max scale après une ligne supplémentaire. Alors fais

gca().set_ylim(top=new_top) # for example

et exécutez à nouveau la fonction resadjust.

14
Tompa

J'ai développé une solution inélégante. Considérons que nous avons l’axe X et aussi une liste d’étiquettes pour chaque point de X.

import matplotlib.pyplot as plt

x = [0,1,2,3,4,5]
y = [10,20,15,18,7,19]
xlabels = ['jan','feb','mar','apr','may','jun']
xlabelsnew = []
for i in xlabels:
    if i not in ['feb','jun']:
        i = ' '
        xlabelsnew.append(i)
    else:
        xlabelsnew.append(i)
plt.plot(x,y)
plt.xticks(range(0,len(x)),xlabels,rotation=45)
plt.show()
plt.plot(x,y)
plt.xticks(range(0,len(x)),xlabelsnew,rotation=45)
plt.show()
8
Deninhos
xmarks=[i for i in range(1,length+1,1)]

plt.xticks(xmarks)

Cela a fonctionné pour moi

si vous voulez des ticks compris entre [1,5] (1 et 5 inclus), remplacez

length = 5
2
Piyush Gupta

Voici une implémentation pure python de la fonctionnalité désirée, qui traite toutes les séries numériques (int ou float) avec des valeurs positives, négatives ou mélangées:

def computeTicks (x, step = 5):
    """
    Computes domain with given step encompassing series x
    @ params
    x    - Required - A list-like object of integers or floats
    step - Optional - Tick frequency
    """
    import math as Math
    xMax, xMin = Math.ceil(max(x)), Math.floor(min(x))
    dMax, dMin = xMax + abs((xMax % step) - step) + (step if (xMax % step != 0) else 0), xMin - abs((xMin % step))
    return range(dMin, dMax, step)

Exemple de sortie:

# Negative to Positive
series = [-2, 18, 24, 29, 43]
print(list(computeTicks(series)))

[-5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45]

# Negative to 0
series = [-30, -14, -10, -9, -3, 0]
print(list(computeTicks(series)))

[-30, -25, -20, -15, -10, -5, 0]

# 0 to Positive
series = [19, 23, 24, 27]
print(list(computeTicks(series)))

[15, 20, 25, 30]

# Floats
series = [1.8, 12.0, 21.2]
print(list(computeTicks(series)))

[0, 5, 10, 15, 20, 25]

# Step – 100
series = [118.3, 293.2, 768.1]
print(list(computeTicks(series, step = 100)))

[100, 200, 300, 400, 500, 600, 700, 800]

Et exemple d'utilisation:

import matplotlib.pyplot as plt

x = [0,5,9,10,15]
y = [0,1,2,3,4]
plt.plot(x,y)
plt.xticks(computeTicks(x))
plt.show()
1
Greenstick