Сохранить подзаговор в matplotlib - PullRequest
42 голосов
/ 01 декабря 2010

Можно ли сохранить (в png) отдельный субплот в фигуре matplotlib? Допустим, у меня есть

import pyplot.matplotlib as plt
ax1 = plt.subplot(121)
ax2 = plt.subplot(122)
ax1.plot([1,2,3],[4,5,6])    
ax2.plot([3,4,5],[7,8,9])

Можно ли сохранить каждый из двух вспомогательных участков в разные файлы или хотя бы скопировать их отдельно в новую фигуру, чтобы сохранить их?

Я использую matplotlib версии 1.0.0 на RHEL 5.

Спасибо

Роберт

Ответы [ 2 ]

69 голосов
/ 01 декабря 2010

Хотя @Eli совершенно верно, что обычно в этом нет особой необходимости, это возможно. savefig принимает аргумент bbox_inches, который можно использовать для выборочного сохранения только части фигуры в изображение.

Вот краткий пример:

import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np

# Make an example plot with two subplots...
fig = plt.figure()
ax1 = fig.add_subplot(2,1,1)
ax1.plot(range(10), 'b-')

ax2 = fig.add_subplot(2,1,2)
ax2.plot(range(20), 'r^')

# Save the full figure...
fig.savefig('full_figure.png')

# Save just the portion _inside_ the second axis's boundaries
extent = ax2.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
fig.savefig('ax2_figure.png', bbox_inches=extent)

# Pad the saved area by 10% in the x-direction and 20% in the y-direction
fig.savefig('ax2_figure_expanded.png', bbox_inches=extent.expanded(1.1, 1.2))

Полная цифра: Full Example Figure


Площадь внутри Второй участок: Inside second subplot


Площадь вокруг второго участка, заполненная на 10% в направлении x и на 20% в направлении y: Full second subplot

20 голосов
/ 18 октября 2014

Применяя функцию full_extent() в ответе @Joe 3 года спустя от здесь , вы можете получить именно то, что искал ОП.В качестве альтернативы, вы можете использовать Axes.get_tightbbox(), что дает немного более жесткий ограничивающий прямоугольник

import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
from matplotlib.transforms import Bbox

def full_extent(ax, pad=0.0):
    """Get the full extent of an axes, including axes labels, tick labels, and
    titles."""
    # For text objects, we need to draw the figure first, otherwise the extents
    # are undefined.
    ax.figure.canvas.draw()
    items = ax.get_xticklabels() + ax.get_yticklabels() 
#    items += [ax, ax.title, ax.xaxis.label, ax.yaxis.label]
    items += [ax, ax.title]
    bbox = Bbox.union([item.get_window_extent() for item in items])

    return bbox.expanded(1.0 + pad, 1.0 + pad)

# Make an example plot with two subplots...
fig = plt.figure()
ax1 = fig.add_subplot(2,1,1)
ax1.plot(range(10), 'b-')

ax2 = fig.add_subplot(2,1,2)
ax2.plot(range(20), 'r^')

# Save the full figure...
fig.savefig('full_figure.png')

# Save just the portion _inside_ the second axis's boundaries
extent = full_extent(ax2).transformed(fig.dpi_scale_trans.inverted())
# Alternatively,
# extent = ax.get_tightbbox(fig.canvas.renderer).transformed(fig.dpi_scale_trans.inverted())
fig.savefig('ax2_figure.png', bbox_inches=extent)

Я бы опубликовал фото, но мне не хватает очков репутации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...