So entfernen Sie Frames aus matplotlib (pyplot.figure vs matplotlib.figure) (frameon = False Problematisch in matplotlib)

160

Um den Rahmen in der Abbildung zu entfernen, schreibe ich

frameon=False

funktioniert perfekt mit pyplot.figure, entfernt aber matplotlib.Figurenur den grauen Hintergrund, der Rahmen bleibt. Außerdem möchte ich nur, dass die Linien angezeigt werden und der Rest der Abbildung transparent ist.

mit pyplot kann ich machen was ich will, ich will es mit matplotlib machen aus einem langen grund, den ich lieber nicht erwähnen möchte, um meine frage zu erweitern.

Emmet B.
quelle
Können Sie klarstellen, was Sie tun? (dh ein Beispiel zeigen) Verwenden Sie savefig? (Wenn ja, wird alles überschrieben, was Sie beim Speichern der Abbildung festgelegt haben.) Funktioniert die manuelle Einstellung fig.patch.set_visible(False)?
Joe Kington
Ich benutze canvas.print_png (Antwort), nicht savefig.
Emmet B

Antworten:

178

Wenn Sie verwenden savefig, beachten Sie zunächst, dass die Hintergrundfarbe der Figur beim Speichern überschrieben wird, sofern Sie nichts anderes angeben (z fig.savefig('blah.png', transparent=True). B. ).

Um jedoch den Hintergrund der Achsen und der Figur auf dem Bildschirm zu entfernen, müssen Sie beide festlegen ax.patchund fig.patchunsichtbar sein.

Z.B

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)

Geben Sie hier die Bildbeschreibung ein

(Natürlich kann man auf dem weißen Hintergrund von SO keinen Unterschied erkennen, aber alles ist transparent ...)

Wenn Sie nichts anderes als die Linie anzeigen möchten, schalten Sie die Achse ebenfalls aus, indem Sie 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)

Geben Sie hier die Bildbeschreibung ein

In diesem Fall möchten Sie möglicherweise, dass die Achsen die vollständige Zahl einnehmen. Wenn Sie die Position der Achsen manuell angeben, können Sie festlegen, dass die vollständige Abbildung übernommen werden soll (alternativ können Sie diese verwenden subplots_adjust, dies ist jedoch für den Fall einer einzelnen Achse einfacher).

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)

Geben Sie hier die Bildbeschreibung ein

Joe Kington
quelle
Damit ist das halbe Problem gelöst. Ich möchte aber auch, dass dieses schwarze Rahmenrechteck unsichtbar ist. Es sollte also nur die blaue Linie sichtbar sein.
Emmet B
5
Na ja, in diesem Fall ist es noch einfacher. Verwenden ax.axis('off')Sie einfach (Sie müssen den Figurenrahmen auch noch ausschalten).
Joe Kington
danke, gibt es eine Möglichkeit, Ticklabels zu behalten, wie zum Beispiel: Ich möchte nur Etiketten ax.set_yticklabels(('G1', 'G2', 'G3'))
Emmet B
Das ist großartig, ich habe es für eine andere Anwendung hier verwendet: stackoverflow.com/questions/4092927/…
cxrodgers
Das print_png()löst TypeError: write() argument must be str, not bytesbei Python 3 eine Ausnahme für mich aus. Das Öffnen der Datei als write binary ( 'wb') ist erforderlich, damit sie funktioniert.
Gabriel Jablonski
243

ax.axis('off'), wird, wie Joe Kington betonte, alles außer der eingezeichneten Linie entfernen.

Wenn Sie nur den Rahmen (Rand) entfernen und Beschriftungen, Ticker usw. beibehalten möchten, können Sie dies tun, indem Sie auf das spinesObjekt auf der Achse zugreifen . Bei einem Achsenobjekt axsollte Folgendes die Ränder auf allen vier Seiten entfernen:

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

Und im Falle des Entfernens xund der yZecken aus der Handlung:

 ax.get_xaxis().set_ticks([])
 ax.get_yaxis().set_ticks([])
Peeol
quelle
1
Ich mag dies, um die oberen und rechten Stacheln loszuwerden
Adrian Torrie
5
Nur zum Hinzufügen: Wenn Sie auch die Zecken entfernen möchten: ax.yaxis.set_ticks_position('left') ax.xaxis.set_ticks_position('bottom')
JLT
4
Verwenden Sie außerdem ax = gca (), um ein Achsenobjekt zu erstellen, falls Sie noch keines haben.
Camerononroytaylor
2
Dies sollte die akzeptierte Antwort sein. "ax.axis (" off ")" entfernt alles wie: x- und y-Beschriftungen, x- und y-Häkchen und alle (4) Ränder aus dem Plot. Zur besseren Anpassung sollte jedes Element anders behandelt werden.
Sanchit
66

Der einfachste Weg, den hässlichen Rahmen in neueren Versionen von matplotlib loszuwerden:

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

Wenn Sie wirklich immer den objektorientierten Ansatz verwenden müssen, dann tun Sie : ax.set_frame_on(False).

neves
quelle
2
Danke dir! Dies ist wahrscheinlich die sauberste Lösung!
Kattia
2
Bei der Verwendung des objektorientierten Ansatzes hatte ich Erfolg ax.set_frame_on(False), was dasselbe bewirkt. Vielleicht in die obige Antwort aufnehmen.
Floyd4K
58

Aufbauend auf der hervorragenden Antwort von @ peeol können Sie den Rahmen auch entfernen, indem Sie dies tun

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

Um ein Beispiel zu nennen (das gesamte Codebeispiel finden Sie am Ende dieses Beitrags), nehmen wir an, Sie haben ein Balkendiagramm wie dieses.

Geben Sie hier die Bildbeschreibung ein

Sie können den Rahmen mit den obigen Befehlen entfernen und dann entweder die Beschriftungen x-und ytick(Plot nicht gezeigt) beibehalten oder sie auch entfernen

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

In diesem Fall kann man die Balken dann direkt beschriften; Die endgültige Darstellung könnte folgendermaßen aussehen (Code finden Sie unten):

Geben Sie hier die Bildbeschreibung ein

Hier ist der gesamte Code, der zum Generieren der Diagramme erforderlich ist:

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
quelle
1
Es hat mein Problem behoben.
Emad Aghayi
6

Wie ich hier geantwortet habe , können Sie über Stileinstellungen (Stylesheet oder rcParams) Stacheln aus all Ihren Plots entfernen:

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
quelle
6

Problem

Ich hatte ein ähnliches Problem mit Achsen. Der Klassenparameter ist frameonaber der kwarg ist frame_on. axes_api
>>> plt.gca().set(frameon=False)
AttributeError: Unknown property frameon

Lösung

frame_on

Beispiel

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. West
quelle
5

Ich mache das immer so:

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

So entfernen Sie den Rahmen des Diagramms

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

Ich hoffe das könnte funktionieren

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

sollte den Trick machen.

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

plt.savefig hat diese Optionen für sich, muss nur vorher die Achsen auslösen

mohammad ess
quelle