Cómo eliminar el marco de matplotlib (pyplot.figure vs matplotlib.figure) (frameon = Falso problema en matplotlib)


161

Para eliminar el marco en la figura, escribo

frameon=False

funciona perfectamente con pyplot.figure, pero con matplotlib.Figureeso solo elimina el fondo gris, el marco permanece. Además, solo quiero que se muestren las líneas, y todo el resto de la figura sea transparente.

con pyplot puedo hacer lo que quiera, quiero hacerlo con matplotlib por alguna larga razón que prefiero no mencionar para extender mi pregunta.


¿Puedes aclarar lo que estás haciendo? (es decir, mostrar un ejemplo) ¿Estás usando savefig? (Si es así, anula lo que configuró al guardar la figura). ¿Funciona la configuración manual fig.patch.set_visible(False)?
Joe Kington

Yo uso canvas.print_png (respuesta), no savefig.
Emmet B

Respuestas:


178

En primer lugar, si está utilizando savefig, tenga en cuenta que anulará el color de fondo de la figura al guardar a menos que especifique lo contrario (por ejemplo fig.savefig('blah.png', transparent=True)).

Sin embargo, para eliminar el fondo de los ejes y la figura en la pantalla, deberá configurar ambos ax.patchy fig.patchser invisible.

P.ej

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)

ingrese la descripción de la imagen aquí

(Por supuesto, no se puede ver la diferencia en el fondo blanco de SO, pero todo es transparente ...)

Si no desea mostrar nada más que la línea, apague también el eje 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)

ingrese la descripción de la imagen aquí

En ese caso, sin embargo, es posible que desee hacer que los ejes ocupen la figura completa. Si especifica manualmente la ubicación de los ejes, puede indicarle que tome la cifra completa (alternativamente, puede usar subplots_adjust, pero esto es más simple para el caso de un solo eje).

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)

ingrese la descripción de la imagen aquí


entonces esto resuelve la mitad del problema. Pero también quiero que este rectángulo de marco negro sea invisible. Entonces solo la línea azul debe ser visible.
Emmet B

55
Oh, bueno, en ese caso es aún más simple. Solo use ax.axis('off')(también necesitará desactivar el marco de la figura también).
Joe Kington

gracias, ¿hay alguna manera de mantener las etiquetas, como: Solo quiero etiquetas ax.set_yticklabels(('G1', 'G2', 'G3'))
Emmet B

Esto es genial, lo usé para otra aplicación aquí: stackoverflow.com/questions/4092927/…
cxrodgers

1
La print_png()lanza una TypeError: write() argument must be str, not bytesexcepción para mí en Python 3. Abrir el archivo en formato binario de escritura ( 'wb') que se necesita para que funcione.
Gabriel Jablonski el

244

ax.axis('off'), como señaló Joe Kington, eliminará todo excepto la línea trazada.

Para aquellos que desean eliminar solo el marco (borde) y mantener etiquetas, tickers, etc., uno puede hacerlo accediendo al spinesobjeto en el eje. Dado un objeto de eje ax, lo siguiente debería eliminar los bordes en los cuatro 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)

Y, en caso de eliminar xy ymarcar de la trama:

 ax.get_xaxis().set_ticks([])
 ax.get_yaxis().set_ticks([])

1
Me gusta esto para deshacerme de las espinas superior y derecha
Adrian Torrie

55
Solo para agregar: cuando también desea eliminar las garrapatas: ax.yaxis.set_ticks_position('left') ax.xaxis.set_ticks_position('bottom')
JLT

44
Además, use ax = gca () para crear un objeto de eje si aún no tiene uno.
cameronroytaylor

2
Esta debería ser la respuesta aceptada. "ax.axis (" off ")" elimina todo como: etiquetas x e y, marcas x e y y todos los bordes (4) del gráfico. Para una mejor personalización, cada elemento debe manejarse de manera diferente.
Sanchit

66

La forma más fácil de deshacerse del marco feo en las versiones más recientes de matplotlib:

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

Si realmente debe utilizar siempre el enfoque orientado a objetos, y luego hacer: ax.set_frame_on(False).


2
¡Gracias! ¡Esta es probablemente la solución más limpia!
Kattia

2
Al usar el enfoque orientado a objetos, tuve éxito con ax.set_frame_on(False), que hace lo mismo. Tal vez incluir en la respuesta anterior.
Floyd4K

58

A partir de la excelente respuesta de @peeol , también puede eliminar el marco haciendo

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

Para dar un ejemplo (el ejemplo de código completo se puede encontrar al final de esta publicación), supongamos que tiene un diagrama de barras como este,

ingrese la descripción de la imagen aquí

puede eliminar el marco con los comandos anteriores y luego mantener las etiquetas x-y ytick(el gráfico no se muestra) o eliminarlas también

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

En este caso, uno puede etiquetar las barras directamente; la trama final podría verse así (el código se puede encontrar a continuación):

ingrese la descripción de la imagen aquí

Aquí está todo el código que es necesario para generar las parcelas:

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()

1
Se solucionó mi problema.
Emad Aghayi

6

Como respondí aquí , puede eliminar las espinas de todas sus parcelas a través de la configuración de estilo (hoja de estilo o 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

6

Problema

Tuve un problema similar al usar ejes. El parámetro de clase es frameonpero el kwarg es frame_on. axes_api
>>> plt.gca().set(frameon=False)
AttributeError: Unknown property frameon

Solución

frame_on

Ejemplo

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()

5

Yo solía hacerlo:

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

2

Para eliminar el marco del gráfico

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

Espero que esto funcione


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')

0
plt.box(False)
plt.xticks([])
plt.yticks([])
plt.savefig('fig.png')

debería hacer el truco.


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

plt.savefig tiene esas opciones en sí mismo, solo necesita desactivar los ejes antes

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.