Cách xóa khung khỏi matplotlib (pyplot.figure vs matplotlib.figure) (frameon = Sai Vấn đề trong matplotlib)


160

Để loại bỏ khung trong hình, tôi viết

frameon=False

hoạt động hoàn hảo với pyplot.figure, nhưng với matplotlib.Figurenó chỉ loại bỏ nền màu xám, khung vẫn ở lại. Ngoài ra, tôi chỉ muốn các dòng hiển thị, và tất cả phần còn lại của hình là trong suốt.

với pyplot tôi có thể làm những gì tôi muốn, tôi muốn làm điều đó với matplotlib vì một số lý do lâu dài tôi không muốn đề cập đến để mở rộng câu hỏi của mình.


Bạn có thể làm rõ những gì bạn đang làm? (tức là hiển thị một ví dụ) Bạn đang sử dụng savefig? (Nếu vậy, nó sẽ ghi đè bất cứ thứ gì bạn đặt khi lưu hình.) Cài đặt thủ công có fig.patch.set_visible(False)hoạt động không?
Joe Kington

Tôi sử dụng canvas.print_png (hồi đáp), không lưu savefig.
Emmet B

Câu trả lời:


178

Trước hết, nếu bạn đang sử dụng savefig, hãy lưu ý rằng nó sẽ ghi đè màu nền của hình khi lưu trừ khi bạn chỉ định khác (ví dụ fig.savefig('blah.png', transparent=True)).

Tuy nhiên, để xóa nền của trục và hình trên màn hình, bạn sẽ cần đặt cả hai ax.patchfig.patchở chế độ ẩn.

Ví dụ

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)

nhập mô tả hình ảnh ở đây

(Tất nhiên, bạn không thể nói sự khác biệt trên nền trắng của SO, nhưng mọi thứ đều trong suốt ...)

Nếu bạn không muốn hiển thị bất cứ thứ gì ngoài dòng, hãy tắt trục bằng cách sử dụng 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)

nhập mô tả hình ảnh ở đây

Tuy nhiên, trong trường hợp đó, bạn có thể muốn làm cho các trục chiếm hết hình. Nếu bạn chỉ định thủ công vị trí của các trục, bạn có thể yêu cầu nó chiếm toàn bộ hình (thay vào đó, bạn có thể sử dụng subplots_adjust, nhưng điều này đơn giản hơn đối với trường hợp của một trục).

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)

nhập mô tả hình ảnh ở đây


vì vậy điều này giải quyết một nửa vấn đề. Nhưng tôi cũng muốn hình chữ nhật khung màu đen này là vô hình. Vì vậy, chỉ có thể nhìn thấy dòng màu xanh.
Emmet B

5
Oh, tốt, trong trường hợp đó thậm chí còn đơn giản hơn. Chỉ cần sử dụng ax.axis('off')(bạn vẫn sẽ cần phải tắt khung hình).
Joe Kington

cảm ơn, có cách nào để giữ ticklabels không, chẳng hạn như: Tôi chỉ muốn nhãn ax.set_yticklabels(('G1', 'G2', 'G3'))
Emmet B

Điều này thật tuyệt, tôi đã sử dụng nó cho một ứng dụng khác ở đây: stackoverflow.com/questions
40292927 / Giả

Việc print_png()ném một TypeError: write() argument must be str, not bytesngoại lệ cho tôi trên python 3. Mở tệp dưới dạng write binary ( 'wb') là cần thiết để nó hoạt động.
Gabriel Jablonski

243

ax.axis('off'), như Joe Kington đã chỉ ra, loại bỏ tất cả mọi thứ trừ đường kẻ được vẽ.

Đối với những người muốn chỉ loại bỏ khung (viền) và giữ nhãn, đánh dấu, v.v., người ta có thể làm điều đó bằng cách truy cập vào spinesđối tượng trên trục. Cho một đối tượng trục ax, sau đây sẽ loại bỏ các đường viền ở cả bốn phía:

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

Và, trong trường hợp loại bỏ xvà đánh ydấu từ cốt truyện:

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

1
Tôi thích điều này vì đã loại bỏ các gai trên cùng và bên phải
Adrian Torrie

5
Chỉ cần thêm: Khi bạn cũng muốn xóa dấu tick: ax.yaxis.set_ticks_position('left') ax.xaxis.set_ticks_position('bottom')
JLT

4
Ngoài ra, sử dụng ax = gca () để tạo đối tượng trục nếu bạn chưa có.
cameronroytaylor

2
Đây phải là câu trả lời được chấp nhận. "Ax.axis (" tắt ")" xóa mọi thứ như: nhãn x và y, dấu x và y và tất cả (4) đường viền khỏi cốt truyện. Để tùy chỉnh tốt hơn, mỗi yếu tố nên được xử lý khác nhau.
Sanchit

66

Cách dễ nhất để thoát khỏi khung hình xấu xí trong các phiên bản mới hơn của matplotlib:

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

Nếu bạn thực sự phải luôn luôn sử dụng cách tiếp cận hướng đối tượng, thì hãy làm : ax.set_frame_on(False).


2
Cảm ơn bạn! Đây có lẽ là giải pháp sạch nhất!
Kattia

2
Khi sử dụng phương pháp hướng đối tượng, tôi đã thành công với ax.set_frame_on(False), điều này cũng tương tự. Có thể bao gồm trong câu trả lời trên.
Floyd4K

58

Xây dựng câu trả lời tuyệt vời của @ peeol , bạn cũng có thể xóa khung bằng cách thực hiện

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

Để đưa ra một ví dụ (có thể tìm thấy toàn bộ mẫu mã ở cuối bài này), giả sử bạn có một biểu đồ thanh như thế này,

nhập mô tả hình ảnh ở đây

bạn có thể loại bỏ khung bằng các lệnh ở trên và sau đó giữ x-yticknhãn (âm mưu không được hiển thị) hoặc loại bỏ chúng cũng như làm

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

Trong trường hợp này, người ta có thể dán nhãn các thanh trực tiếp; cốt truyện cuối cùng có thể trông như thế này (mã có thể được tìm thấy bên dưới):

nhập mô tả hình ảnh ở đây

Đây là toàn bộ mã cần thiết để tạo các ô:

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
Nó đã khắc phục vấn đề của tôi.
Emad Aghayi

6

Như tôi đã trả lời ở đây , bạn có thể xóa các gai khỏi tất cả các lô của mình thông qua cài đặt kiểu (biểu định kiểu hoặc 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

Vấn đề

Tôi đã có một vấn đề tương tự bằng cách sử dụng các trục. Tham số lớp là frameonnhưng kwarg là frame_on. axes_api
>>> plt.gca().set(frameon=False)
AttributeError: Unknown property frameon

Giải pháp

frame_on

Thí dụ

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

Tôi sử dụng để làm như vậy:

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

2

Để loại bỏ khung của biểu đồ

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

Tôi hy vọng điều này có thể làm việc


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.axis('off')
plt.savefig(file_path, bbox_inches="tight", pad_inches = 0)

plt.savefig có các tùy chọn đó, chỉ cần tắt trục trước

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.