Как удалить фрейм из matplotlib (pyplot.figure vs matplotlib.figure) (frameon = False Проблемно в matplotlib)

161

Чтобы снять рамку на рисунке, я пишу

frameon=False

отлично работает pyplot.figure, но при matplotlib.Figureэтом удаляет только серый фон, рамка остается. Кроме того, я хочу, чтобы показывались только линии, а все остальное на рисунке было прозрачным.

с pyplot я могу делать то, что хочу, я хочу сделать это с matplotlib по какой-то долгой причине, которую я не хочу упоминать, чтобы расширить мой вопрос.

Эммет Б
источник
Можете ли вы уточнить, что вы делаете? (т.е. покажите пример) Вы используете savefig? (Если это так, он переопределяет все, что вы установили при сохранении рисунка.) Работает ли ручная настройка fig.patch.set_visible(False)?
Джо Кингтон
Я использую canvas.print_png (response), а не savefig.
Эммет Б

Ответы:

178

Прежде всего, если вы используете savefig, имейте в виду, что при сохранении он переопределит цвет фона фигуры, если не указано иное (например fig.savefig('blah.png', transparent=True)).

Однако, чтобы убрать фон осей и фигуры на экране, вам нужно установить оба параметра ax.patchи fig.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)

введите описание изображения здесь

Джо Кингтон
источник
так что это решает половину проблемы. Но я также хочу, чтобы этот прямоугольник с черной рамкой был невидимым. Так что должна быть видна только синяя линия.
Эммет Б
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исключение для меня на Python 3. Открытие файла в записи двоичного файла ( 'wb') необходим для его работы.
Габриэль Яблонски
244

ax.axis('off'), как указал Джо Кингтон, удалит все, кроме намеченной линии.

Для тех, кто хочет удалить только рамку (рамку) и сохранить метки, тикеры и т. Д., Это можно сделать, обратившись к 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([])
peeol
источник
1
Мне нравится это, чтобы избавиться от верхних и правых шипов
Адриан Торри
5
Просто чтобы добавить: Когда вы также хотите снять ax.yaxis.set_ticks_position('left') ax.xaxis.set_ticks_position('bottom')
JLT
4
Также используйте ax = gca () для создания объекта оси, если у вас его еще нет.
Камеронройтайлор
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
Спасибо! Это, наверное, самое чистое решение!
Катя
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()
Cleb
источник
1
Это исправило мою проблему.
Эмад Агайи
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
HHH
источник
6

проблема

У меня была похожая проблема с использованием осей. Параметр класса есть, frameonно kwarg есть frame_on. axes_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()
А. Вест
источник
5

Я использую для этого:

from pylab import *
axes(frameon = 0)
...
show()
alinsoar
источник
2

Убрать рамку графика

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

Я надеюсь, что это может сработать

Шабих Шаккир
источник
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')

должен сделать свое дело.

user3496912
источник
0
plt.axis('off')
plt.savefig(file_path, bbox_inches="tight", pad_inches = 0)

У plt.savefig есть эти опции, просто нужно отключить оси перед

Мохаммед Эсс
источник