Comment supprimer le cadre de matplotlib (pyplot.figure vs matplotlib.figure) (frameon = False Problematic dans matplotlib)

161

Pour supprimer le cadre de la figure, j'écris

frameon=False

fonctionne parfaitement avec pyplot.figure, mais avec matplotlib.Figurecela ne supprime que le fond gris, le cadre reste. De plus, je veux que les lignes ne soient affichées et que tout le reste de la figure soit transparent.

avec pyplot je peux faire ce que je veux, je veux le faire avec matplotlib pour une longue raison que je préfère ne pas mentionner pour étendre ma question.

Emmet B
la source
Pouvez-vous clarifier ce que vous faites? (par exemple, montrez un exemple) Utilisez-vous savefig? (Si tel est le cas, il remplace ce que vous avez défini lors de l'enregistrement de la figure.) Le réglage manuel fig.patch.set_visible(False)fonctionne-t-il?
Joe Kington
J'utilise canvas.print_png (response), pas savefig.
Emmet B

Réponses:

178

Tout d'abord, si vous utilisez savefig, sachez que cela remplacera la couleur d'arrière-plan de la figure lors de l'enregistrement, sauf indication contraire (par exemple fig.savefig('blah.png', transparent=True)).

Cependant, pour supprimer l'arrière-plan des axes et de la figure à l'écran, vous devez définir les deux ax.patchet fig.patchêtre invisible.

Par exemple

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)

entrez la description de l'image ici

(Bien sûr, vous ne pouvez pas faire la différence sur le fond blanc de SO, mais tout est transparent ...)

Si vous ne voulez rien afficher d'autre que la ligne, désactivez également l'axe en utilisant 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)

entrez la description de l'image ici

Dans ce cas, cependant, vous voudrez peut-être que les axes reprennent la figure complète. Si vous spécifiez manuellement l'emplacement des axes, vous pouvez lui dire de prendre la figure complète (vous pouvez également utiliser subplots_adjust, mais c'est plus simple pour le cas d'un seul axe).

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)

entrez la description de l'image ici

Joe Kington
la source
donc cela résout la moitié du problème. Mais je veux aussi que ce rectangle de cadre noir soit invisible. Ainsi, seule la ligne bleue doit être visible.
Emmet B
5
Oh, eh bien, dans ce cas, c'est encore plus simple. Utilisez simplement ax.axis('off')(vous devrez également désactiver le cadre de la figure).
Joe Kington
merci, existe-t-il un moyen de conserver les étiquettes, telles que: Je ne veux que des étiquettes ax.set_yticklabels(('G1', 'G2', 'G3'))
Emmet B
C'est génial, je l'ai utilisé pour une autre application ici: stackoverflow.com/questions/4092927/…
cxrodgers
1
Le print_png()jette une TypeError: write() argument must be str, not bytesexception pour moi sur python 3. L'ouverture du fichier en tant que write binary ( 'wb') est nécessaire pour que cela fonctionne.
Gabriel Jablonski
244

ax.axis('off'), comme l'a souligné Joe Kington, supprimera tout sauf la ligne tracée.

Pour ceux qui souhaitent uniquement supprimer le cadre (bordure), et conserver les étiquettes, les tickers, etc., on peut le faire en accédant à l' spinesobjet sur l'axe. Étant donné un objet axe ax, les éléments suivants devraient supprimer les bordures des quatre côtés:

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

Et, en cas de suppression xet de ycoches de l'intrigue:

 ax.get_xaxis().set_ticks([])
 ax.get_yaxis().set_ticks([])
peeol
la source
1
J'aime ça pour me débarrasser des épines supérieures et droites
Adrian Torrie
5
Juste pour ajouter: Lorsque vous souhaitez également supprimer les coches: ax.yaxis.set_ticks_position('left') ax.xaxis.set_ticks_position('bottom')
JLT
4
Aussi, utilisez ax = gca () pour créer un objet axe si vous n'en avez pas déjà un.
cameronroytaylor
2
Cela devrait être la réponse acceptée. "ax.axis (" off ")" supprime tout comme: les étiquettes x et y, les graduations x et y et toutes les (4) bordures du tracé. Pour une meilleure personnalisation, chaque élément doit être traité différemment.
Sanchit
66

Le moyen le plus simple de se débarrasser du cadre laid dans les nouvelles versions de matplotlib:

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

Si vous devez vraiment toujours utiliser l'approche orientée objet, puis faites: ax.set_frame_on(False).

neves
la source
2
Je vous remercie! C'est probablement la solution la plus propre!
Kattia
2
Lors de l'utilisation de l'approche orientée objet, j'ai eu du succès avec ax.set_frame_on(False), qui fait la même chose. Peut-être inclure dans la réponse ci-dessus.
Floyd4K
58

En vous appuyant sur l'excellente réponse de @ peeol , vous pouvez également supprimer le cadre en faisant

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

Pour donner un exemple (l'intégralité de l'exemple de code se trouve à la fin de cet article), disons que vous avez un graphique à barres comme celui-ci,

entrez la description de l'image ici

vous pouvez supprimer le cadre avec les commandes ci-dessus, puis conserver les étiquettes x-et ytick(tracé non affiché) ou les supprimer également en faisant

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

Dans ce cas, on peut alors étiqueter directement les barres; le tracé final pourrait ressembler à ceci (le code peut être trouvé ci-dessous):

entrez la description de l'image ici

Voici tout le code nécessaire pour générer les tracés:

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
la source
1
Cela a résolu mon problème.
Emad Aghayi le
6

Comme je l'ai répondu ici , vous pouvez supprimer les épines de tous vos tracés via les paramètres de style (feuille de style 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
la source
6

Problème

J'ai eu un problème similaire en utilisant des axes. Le paramètre de classe est frameonmais le kwarg l'est frame_on. axes_api
>>> plt.gca().set(frameon=False)
AttributeError: Unknown property frameon

Solution

frame_on

Exemple

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. Ouest
la source
5

J'utilise pour le faire:

from pylab import *
axes(frameon = 0)
...
show()
Alinsoar
la source
2

Pour supprimer le cadre du graphique

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

J'espère que cela pourrait fonctionner

Shabeeh Shakkir
la source
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
la source
0
plt.box(False)
plt.xticks([])
plt.yticks([])
plt.savefig('fig.png')

devrait faire l'affaire.

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

plt.savefig a ces options en soi, il suffit de désactiver les axes avant

mohammad ess
la source