reduzindo o número de ticks de plotagem

160

Eu tenho muitos ticks no meu gráfico e eles estão se encontrando.

Como posso reduzir o número de ticks?

Por exemplo, eu tenho carrapatos:

1E-6, 1E-5, 1E-4, ... 1E6, 1E7

E eu só quero:

1E-5, 1E-3, ... 1E5, 1E7

Eu tentei brincar com o LogLocator, mas não consegui descobrir isso.

jlconlin
fonte

Respostas:

266

Como alternativa, se você deseja simplesmente definir o número de ticks enquanto permite que o matplotlib os posicione (atualmente apenas com MaxNLocator), existe pyplot.locator_params,

pyplot.locator_params(nbins=4)

Você pode especificar um eixo específico nesse método, conforme mencionado abaixo; o padrão é ambos:

# To specify the number of ticks on both or any single axes
pyplot.locator_params(axis='y', nbins=6)
pyplot.locator_params(axis='x', nbins=10)
bgamari
fonte
27
Essa foi uma ótima sugestão, também poder especificar pyplot.locator_params(axis = 'x', nbins = 4)(ou axis = 'y') tornar o processo realmente simples. Obrigado @bgamari!
Benjaminmgross
8
Com escala de log, isso funcionou em numticksvez denbins
meduz
1
@bgamari, você poderia adicionar a numtickssolução para gráficos logarítmicos, como apontado por @meduz?
Løiten
7
Isso não parece colocar os rótulos onde deveriam estar. Por exemplo, se os rótulos de marca de seleção originais estão [0, 1, ..., 99]e agora se definem nticks=10, os novos rótulos esparsos serão colocados dez vezes mais afastados ao longo do eixo, ou seja, agora 1ficarão onde 9estava, 2onde 19estava ... e 9onde 99estava.
Vim
2
Verifique seus resultados antes de confiar neste método. @Vim está correto. Os valores dos ticks serão colocados incorretamente.
David J.
53

Se alguém ainda receber essa página nos resultados da pesquisa:

fig, ax = plt.subplots()

plt.plot(...)

every_nth = 4
for n, label in enumerate(ax.xaxis.get_ticklabels()):
    if n % every_nth != 0:
        label.set_visible(False)
Katerina
fonte
7
Isso realmente funcionou contra todas as outras respostas que não fizeram nada. Obrigado :)
faizan 25/05
Bem feito. Levei um tempo para encontrar isso, mas fez o que eu queria.
John
Obrigado, isso garante que os rótulos restantes estejam nas posições corretas. Uma etapa adicional que melhoraria essa resposta é também remover a marca de seleção.
David J.
Ótima resposta simples - surpreendeu nenhum método personalizado conhecido pela comunidade SO. Isso seria uma adição valiosa à lib?
jabberwocky
32

Para resolver o problema de personalização e aparência dos ticks, consulte o guia Localizadores de ticks no site matplotlib

ax.xaxis.set_major_locator(plt.MaxNLocator(3))

Definiria o número total de ticks no eixo x como 3 e o distribuiria uniformemente pelo eixo.

Há também um bom tutorial sobre isso

Prageeth Jayathissa
fonte
Selecione apenas os três primeiros índices de data e hora. quando chegar machado de pandas.DataFrame.plot ax = df.plot()
Mithril
@Mithril desculpe, eu não entendo bem o seu comentário. Você poderia por favor elaborar?
Prageeth Jayathissa
Se eu tiver um df ( pandas.DataFrame) com índice datetime [2019-01-01, ... 2019-11-01], call ax = df.plot(), retorne um objeto de figura. a chamada ax.xaxis.set_major_locator(plt.MaxNLocator(3)) mostra apenas o primeiro índice 3 [2019-01-01, 2019-01-02, 2019-01-03].
Mithril
1
@Mithril, df.plot()muitas vezes exibe o minor_locator, então você pode querer tentar ax1.xaxis.set_minor_locator(plt.MaxNLocator(3)). Lembre-se também de substituir o 3número de ticks que deseja exibir. Para pandas timeseries Eu recomendo import matplotlib.dates as mdatese executar ax.xaxis.set_minor_locator(mdates.MonthLocator(interval = 1))comax.xaxis.set_minor_formatter(mdates.DateFormatter('%m-%Y'))
Prageeth Jayathissa
20

Há uma set_ticks()função para objetos de eixo.

André Caron
fonte
4
Isso funcionaria se eu soubesse de antemão o que queria. O exemplo que dei acima foi apenas um exemplo. Não sei o que são os carrapatos, só sei que quero menos deles, ou seja, todos os outros.
jlconlin
10
Você pode chamar get_xticks()ou get_yticks()primeiro o objeto de eixos, editar conforme necessário e depois passar a lista de volta para set_ticks().
user812786
4
Eu não tenho set_ticks(), mas eu tenho set_xticks()e set_yticks(). Esses são atributos dos objetos dos eixos, não do eixo. Talvez isso tenha mudado nos últimos dois anos.
Gauthier
2
Não tenho certeza se devo, algumas pessoas acharam sua resposta útil, e apenas porque é diferente para mim não significa que é para todos.
Gauthier
1
Um exemplo ajudaria muito a tornar esta resposta útil.
Richard
10

caso alguém ainda precise, e como nada aqui realmente funcionou para mim, criei uma maneira muito simples que mantém a aparência do gráfico gerado "como está", enquanto fixa o número de ticks exatamente N:

import numpy as np
import matplotlib.pyplot as plt

f, ax = plt.subplots()
ax.plot(range(100))

ymin, ymax = ax.get_ylim()
ax.set_yticks(np.round(np.linspace(ymin, ymax, N), 2))
raphael
fonte
2
Eu tive que modificar a última linha ligeiramente, a fim de obtê-lo para retornar os valores como int em vez de float:ax.set_yticks(np.linspace(int(ymin), int(ymax), N), 2)
Nick Settje
@NickSettje ainda flutua comigo!
Mohd
4

A solução que a @raphael deu é direta e bastante útil.

Ainda assim, os rótulos de marca de seleção exibidos não serão valores amostrados da distribuição original, mas dos índices da matriz retornados por np.linspace(ymin, ymax, N).

Para exibir N valores espaçados igualmente de seus rótulos de marca originais, use o set_yticklabels()método Aqui está um trecho para o eixo y, com rótulos inteiros:

import numpy as np
import matplotlib.pyplot as plt

ax = plt.gca()

ymin, ymax = ax.get_ylim()
custom_ticks = np.linspace(ymin, ymax, N, dtype=int)
ax.set_yticks(custom_ticks)
ax.set_yticklabels(custom_ticks)
Tantris
fonte
Parabéns por este belo ajuste!
Mohd
2

Quando uma escala de log é usada, o número de ticks principais pode ser corrigido com o seguinte comando

import matplotlib.pyplot as plt

....

plt.locator_params(numticks=12)
plt.show()

O valor definido como numticksdetermina o número de marcações do eixo a serem exibidas.

Créditos à postagem de @ bgamari pela introdução da locator_params()função, mas o nticksparâmetro gera um erro quando uma escala de log é usada.

Ébe Isaac
fonte
A pergunta e a resposta são para o matplotlib anterior, ou seja, 1 e você está se referindo ao 2. #
Dawid Laszuk