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


160

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

frameon=False

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

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


您能说明您在做什么吗?(即显示示例)您在使用savefig吗?(如果是这样,它将覆盖您在保存图形时设置的任何内容。)手动设置是否fig.patch.set_visible(False)有效?
乔·肯顿

我使用canvas.print_png(response),而不是savefig。
Emmet B

Answers:


178

首先,如果您使用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)

在此处输入图片说明


所以这解决了一半的问题。但我也希望此黑框矩形不可见。因此,只有蓝线应该可见。
Emmet B

5
哦,好吧,在那种情况下,它甚至更简单。只需使用ax.axis('off')(您仍然需要关闭数字框)。
乔·肯顿

谢谢,有没有一种方法可以保留刻度标签,例如:我只想要标签 ax.set_yticklabels(('G1', 'G2', 'G3'))
Emmet B

这是伟大的,我用了另一个应用程序的位置:stackoverflow.com/questions/4092927/...
cxrodgers

1
print_png()抛出一个TypeError: write() argument must be str, not bytes关于蟒蛇3.打开文件写二进制文件(对我来说异常'wb')需要为它工作。
加布里埃尔·雅布隆斯基

243

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

1
我喜欢这个为摆脱顶部和右刺
阿德里安·托里

5
只需添加:当您还想删除刻度时: ax.yaxis.set_ticks_position('left') ax.xaxis.set_ticks_position('bottom')
JLT

4
另外,如果还没有轴对象,请使用ax = gca()创建轴对象。
cameronroytaylor

2
这应该是公认的答案。“ ax.axis(” off“)”从图形中删除所有内容,例如:x和y标签,x和y刻度以及所有(4)边框。为了更好地进行自定义,每个元素应以不同的方式处理。
桑契特

66

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

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

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


2
谢谢!这可能是最干净的解决方案!
卡蒂亚'18

2
使用面向对象的方法时,我成功完成了ax.set_frame_on(False),它具有相同的作用。也许包括在以上答案中。
Floyd4K

58

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

1
它解决了我的问题。
Emad Aghayi

6

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

问题

我在使用轴时遇到了类似的问题。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()



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

应该可以。


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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.