如何从matplotlib中删除框架(pyplot.figure与matplotlib.figure)(frameon = False在matplotlib中有问题)

问题:如何从matplotlib中删除框架(pyplot.figure与matplotlib.figure)(frameon = False在matplotlib中有问题)

为了删除图中的框架,我写

frameon=False

可以完美搭配使用pyplot.figure,但matplotlib.Figure只能去除灰色背景,框架保持不变。另外,我只希望显示线条,其余所有图都是透明的。

使用pyplot我可以做我想做的事,我想用matplotlib做它有很长的原因,我不想提及扩展我的问题。

To remove frame in figure, I write

frameon=False

works perfect with pyplot.figure, but with matplotlib.Figure it only removes the gray background, the frame stays . Also, I only want the lines to show, and all the rest of figure be transparent.

with pyplot I can do what I want, I want to do it with matplotlib for some long reason I ‘d rather not mention to extend my question.


回答 0

首先,如果您使用savefig,请注意,除非另外指定(例如fig.savefig('blah.png', transparent=True)),否则保存时它将覆盖图形的背景颜色。

但是,要在屏幕上删除轴和图形的背景,您需要同时设置它们ax.patchfig.patch使其不可见。

例如

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)

(当然,您不能说出SO的白色背景有什么区别,但是一切都是透明的…)

如果您不想显示该线以外的任何东西,也可以使用关闭轴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)

但是,在这种情况下,您可能希望使轴占据整个图形。如果您手动指定轴的位置,则可以告诉它占用完整的数字(或者,可以使用subplots_adjust,但是对于单轴来说更简单)。

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)

First off, if you’re using savefig, be aware that it will override the figure’s background color when saving unless you specify otherwise (e.g. fig.savefig('blah.png', transparent=True)).

However, to remove the axes’ and figure’s background on-screen, you’ll need to set both ax.patch and fig.patch to be invisible.

E.g.

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)

(Of course, you can’t tell the difference on SO’s white background, but everything is transparent…)

If you don’t want to show anything other than the line, turn the axis off as well using 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)

In that case, though, you may want to make the axes take up the full figure. If you manually specify the location of the axes, you can tell it to take up the full figure (alternately, you can use subplots_adjust, but this is simpler for the case of a single axes).

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)


回答 1

ax.axis('off'),如乔·肯顿(Joe Kington)所指出的那样,请删除除画线外的所有内容。

对于那些只希望删除框架(边框)并保留标签,股票行情指示器等的人,可以通过访问spines轴上的对象来做到这一点。给定轴对象ax,以下内容应删除所有四个边的边界:

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

并且,从情节中删除x和剔除y

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

ax.axis('off'), will as Joe Kington pointed out, remove everything except the plotted line.

For those wanting to only remove the frame (border), and keep labels, tickers etc, one can do that by accessing the spines object on the axis. Given an axis object ax, the following should remove borders on all four sides:

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

And, in case of removing x and y ticks from the plot:

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

回答 2

摆脱matplotlib较新版本中丑陋框架的最简单方法:

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

如果确实必须始终使用面向对象的方法,请执行:ax.set_frame_on(False)

The easiest way to get rid of the the ugly frame in newer versions of matplotlib:

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

If you really must always use the object oriented approach, then do: ax.set_frame_on(False).


回答 3

@peeol的出色答案为基础,您也可以通过以下方法删除框架

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

举个例子(整个代码示例可以在本文的结尾处找到),假设您有一个这样的条形图,

您可以使用上面的命令删除框架,然后保留x-ytick标签(未显示图)或也删除它们

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

在这种情况下,可以直接在条形上贴标签;最终的图看起来像这样(代码可以在下面找到):

这是生成图所必需的全部代码:

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

Building up on @peeol’s excellent answer, you can also remove the frame by doing

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

To give an example (the entire code sample can be found at the end of this post), let’s say you have a bar plot like this,

you can remove the frame with the commands above and then either keep the x- and ytick labels (plot not shown) or remove them as well doing

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

In this case, one can then label the bars directly; the final plot could look like this (code can be found below):

Here is the entire code that is necessary to generate the plots:

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

回答 4

正如我在这里回答的那样,您可以通过样式设置(样式表或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

As I answered here, you can remove spines from all your plots through style settings (style sheet or 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

回答 5

问题

我在使用轴时遇到了类似的问题。class参数为,frameon但kwarg为frame_onaxes_api
>>> plt.gca().set(frameon=False)
AttributeError: Unknown property frameon

frame_on

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

Problem

I had a similar problem using axes. The class parameter is frameon but the kwarg is frame_on. axes_api
>>> plt.gca().set(frameon=False)
AttributeError: Unknown property frameon

Solution

frame_on

Example

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

回答 6

我经常这样做:

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

I use to do so:

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

回答 7

删除图表框架

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

我希望这可以工作

To remove the frame of the chart

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

I hope this could work


回答 8

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

回答 9

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

应该可以。

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

should do the trick.


回答 10

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

plt.savefig本身具有这些选项,只需要在关闭轴之前

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

plt.savefig has those options in itself, just need to set axes off before