Como remover o quadro do matplotlib (pyplot.figure vs matplotlib.figure) (frameon = Problema falso no matplotlib)

161

Para remover o quadro da figura, escrevo

frameon=False

funciona perfeitamente com pyplot.figure, mas matplotlib.Figuresó remove o fundo cinza, o quadro permanece. Além disso, só quero que as linhas sejam exibidas e todo o resto da figura seja transparente.

com o pyplot, posso fazer o que quiser, quero fazê-lo com o matplotlib por algum longo motivo que eu prefiro não mencionar para estender minha pergunta.

Emmet B
fonte
Você pode esclarecer o que está fazendo? (ou seja, mostre um exemplo) Você está usando savefig? (Se sim, substitui o que você definiu ao salvar a figura.) A configuração manual fig.patch.set_visible(False)funciona?
31813 Joe Joeton
Eu uso canvas.print_png (resposta), não savefig.
Emmet B

Respostas:

178

Primeiro, se você estiver usando savefig, saiba que ela substituirá a cor de fundo da figura ao salvar, a menos que você especifique o contrário (por exemplo fig.savefig('blah.png', transparent=True)).

No entanto, para remover o plano de fundo dos eixos e da figura na tela, você precisará definir os dois ax.patche fig.patchficar invisível.

Por exemplo

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot(range(10))

for item in [fig, ax]:
    item.patch.set_visible(False)

with open('test.png', 'w') as outfile:
    fig.canvas.print_png(outfile)

insira a descrição da imagem aqui

(Claro, você não pode dizer a diferença no fundo branco da SO, mas tudo é transparente ...)

Se você não quiser mostrar nada além da linha, desligue o eixo também usando ax.axis('off'):

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot(range(10))

fig.patch.set_visible(False)
ax.axis('off')

with open('test.png', 'w') as outfile:
    fig.canvas.print_png(outfile)

insira a descrição da imagem aqui

Nesse caso, porém, convém fazer com que os eixos ocupem a figura inteira. Se você especificar manualmente a localização dos eixos, poderá solicitar que ele assuma a figura completa (como alternativa, você pode usar subplots_adjust, mas isso é mais simples no caso de um único eixo).

import matplotlib.pyplot as plt

fig = plt.figure(frameon=False)
ax = fig.add_axes([0, 0, 1, 1])
ax.axis('off')

ax.plot(range(10))

with open('test.png', 'w') as outfile:
    fig.canvas.print_png(outfile)

insira a descrição da imagem aqui

Joe Kington
fonte
então isso resolve metade do problema. Mas também quero que esse retângulo de moldura preta seja invisível. Portanto, apenas a linha azul deve estar visível.
Emmet B
5
Bem, nesse caso é ainda mais simples. Basta usar ax.axis('off')(você também precisará desativar o quadro de figuras).
31813 Joe Joeton
graças, existe uma maneira de manter ticklabels, tais como: Eu quero etiquetas só ax.set_yticklabels(('G1', 'G2', 'G3'))
Emmet B
Isso é ótimo, eu usei-o para outra aplicação aqui: stackoverflow.com/questions/4092927/...
cxrodgers
1
O print_png()lança uma TypeError: write() argument must be str, not bytesexceção para mim em python 3. Abrir o arquivo como gravação binário ( 'wb') é necessária para que ele funcione.
Gabriel Jablonski
244

ax.axis('off'), como Joe Kington apontou, removerá tudo, exceto a linha plotada.

Para aqueles que desejam remover apenas o quadro (borda) e manter etiquetas, tickers etc., pode-se fazer isso acessando o spinesobjeto no eixo. Dado um objeto de eixo ax, o seguinte deve remover bordas nos quatro lados:

ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['left'].set_visible(False)

E, no caso de remover xe ymarcar da trama:

 ax.get_xaxis().set_ticks([])
 ax.get_yaxis().set_ticks([])
peeol
fonte
1
Eu gosto disso para me livrar dos espinhos superior e direito #
Adrian Torrie 28/10
5
Só para adicionar: Quando você também deseja remover os ticks: ax.yaxis.set_ticks_position('left') ax.xaxis.set_ticks_position('bottom')
JLT
4
Além disso, use ax = gca () para criar um objeto de eixo se você ainda não tiver um.
Cameronroytaylor 31/03/19
2
Essa deve ser a resposta aceita. "ax.axis (" off ")" remove tudo como: rótulos x e y, x e y assinalam e todas as (4) bordas da plotagem. Para uma melhor personalização, cada elemento deve ser tratado de maneira diferente.
Sanchit 9/11/19
66

A maneira mais fácil de se livrar do quadro feio nas versões mais recentes do matplotlib:

import matplotlib.pyplot as plt
plt.box(False)

Se você realmente deve sempre usar a abordagem orientada a objetos, em seguida, fazer: ax.set_frame_on(False).

Neves
fonte
2
Obrigado! Esta é provavelmente a solução mais limpa!
Kattia
2
Ao usar a abordagem orientada a objetos, tive sucesso com o ax.set_frame_on(False)que faz a mesma coisa. Talvez inclua na resposta acima.
Floyd4K 01/10/19
58

Com base na excelente resposta do @ peeol , você também pode remover o quadro fazendo

for spine in plt.gca().spines.values():
    spine.set_visible(False)

Para dar um exemplo (todo o exemplo de código pode ser encontrado no final desta postagem), digamos que você tenha um gráfico de barras como este,

insira a descrição da imagem aqui

você pode remover o quadro com os comandos acima e, em seguida, manter os rótulos x-e ytick(plot não mostrado) ou removê-los

plt.tick_params(top='off', bottom='off', left='off', right='off', labelleft='off', labelbottom='on')

Nesse caso, pode-se rotular as barras diretamente; o gráfico final pode ter esta aparência (o código pode ser encontrado abaixo):

insira a descrição da imagem aqui

Aqui está o código inteiro necessário para gerar os gráficos:

import matplotlib.pyplot as plt
import numpy as np

plt.figure()

xvals = list('ABCDE')
yvals = np.array(range(1, 6))

position = np.arange(len(xvals))

mybars = plt.bar(position, yvals, align='center', linewidth=0)
plt.xticks(position, xvals)

plt.title('My great data')
# plt.show()

# get rid of the frame
for spine in plt.gca().spines.values():
    spine.set_visible(False)

# plt.show()
# remove all the ticks and directly label each bar with respective value
plt.tick_params(top='off', bottom='off', left='off', right='off', labelleft='off', labelbottom='on')

# plt.show()

# direct label each bar with Y axis values
for bari in mybars:
    height = bari.get_height()
    plt.gca().text(bari.get_x() + bari.get_width()/2, bari.get_height()-0.2, str(int(height)),
                 ha='center', color='white', fontsize=15)
plt.show()
Cleb
fonte
1
Corrigiu o meu problema.
Emad Aghayi 04/04
6

Como respondi aqui , você pode remover espinhos de todas as suas plotagens por meio das configurações de estilo (folha de estilo ou rcParams):

import matplotlib as mpl

mpl.rcParams['axes.spines.left'] = False
mpl.rcParams['axes.spines.right'] = False
mpl.rcParams['axes.spines.top'] = False
mpl.rcParams['axes.spines.bottom'] = False
hhh
fonte
6

Problema

Eu tive um problema semelhante usando eixos. O parâmetro da classe é frameonmas o kwarg é frame_on. axes_api
>>> plt.gca().set(frameon=False)
AttributeError: Unknown property frameon

Solução

frame_on

Exemplo

data = range(100)
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot(data)
#ax.set(frameon=False)  # Old
ax.set(frame_on=False)  # New
plt.show()
A. Oeste
fonte
5

Eu costumo fazer isso:

from pylab import *
axes(frameon = 0)
...
show()
alinsoar
fonte
2

Para remover o quadro do gráfico

for spine in plt.gca().spines.values():
  spine.set_visible(False)

Espero que isso funcione

Shabeeh Shakkir
fonte
1
df = pd.DataFrame({
'client_scripting_ms' : client_scripting_ms,
 'apimlayer' : apimlayer, 'server' : server
}, index = index)

ax = df.plot(kind = 'barh', 
     stacked = True,
     title = "Chart",
     width = 0.20, 
     align='center', 
     figsize=(7,5))

plt.legend(loc='upper right', frameon=True)

ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)

ax.yaxis.set_ticks_position('left')
ax.xaxis.set_ticks_position('right')
Taha Kaiyum
fonte
0
plt.box(False)
plt.xticks([])
plt.yticks([])
plt.savefig('fig.png')

deve fazer o truque.

user3496912
fonte
0
plt.axis('off')
plt.savefig(file_path, bbox_inches="tight", pad_inches = 0)

O plt.savefig possui essas opções em si, só precisa desativar os eixos antes de

mohammad ess
fonte