автоматическое приведение изображения matplotlib в соответствие с другой меткой субплота

1

Эта проблема

Я пытаюсь построить изображение рядом с некоторыми данными. Тем не менее, я хотел бы, чтобы изображение расширялось, чтобы быть на одном уровне с метками графика. Например, следующий код (используя этот образ учебника):

# make the incorrect figure
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
fig = plt.figure(figsize=(8,3))
ax_image = plt.subplot(1,2,1)
plt.imshow(mpimg.imread('stinkbug.png'))
plt.subplot(1,2,2)
plt.plot([0,1],[2,3])
plt.ylabel("y")
plt.xlabel("want image flush with bottom of this label")
fig.tight_layout()
ax_image.axis('off')
fig.savefig("incorrect.png")

дает этот сюжет с дополнительными пробелами:

Изображение 174551

Хакерная попытка решения

Мне нужен сюжет, который не пуст. Следующий взломанный код (в духе этой ссылки SO) выполняет следующее:

# make the correct figure with manually changing the size
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
fig = plt.figure(figsize=(8,3))
ax_image = fig.add_axes([0.02,0,0.45,1.0])
plt.imshow(mpimg.imread('stinkbug.png'))
plt.subplot(1,2,2)
plt.plot([0,1],[2,3])
plt.ylabel("y")
plt.xlabel("want image flush with bottom of this label")
fig.tight_layout()
ax_image.axis('off')
fig.savefig("correct.png")

получив следующий рисунок:

Изображение 174551

Вопрос

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

  • 0
    Если мотивация не в том, чтобы тратить пространство, нижняя часть меток изображения должна быть выровнена с нижней частью xlabel графика, верно?
  • 0
    Это хороший момент. Мое окончательное изображение не будет иметь никаких тиков или меток, только внутренняя шкала. Я отредактирую вопрос, чтобы убрать галочки. Я бы хотел, чтобы нижняя часть изображения находилась на одном уровне с нижней частью метки x на другом участке.
Показать ещё 3 комментария
Теги:
data-science
matplotlib
numpy
image

1 ответ

1
Лучший ответ

Вы можете получить объединение ограничивающего прямоугольника правых осей и его метки и установить положение левых осей таким образом, чтобы оно начиналось в вертикальном положении ограничивающего блока объединения. Следующее предполагает некоторый автоматический аспект на изображении, то есть изображение искажается в одном направлении.

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import matplotlib.transforms as mtrans

fig, (ax_image, ax) = plt.subplots(ncols=2, figsize=(8,3))

ax_image.imshow(mpimg.imread('https://matplotlib.org/_images/stinkbug.png'))
ax_image.set_aspect("auto")
ax.plot([0,1],[2,3])
ax.set_ylabel("y")
xlabel = ax.set_xlabel("want image flush with bottom of this label")
fig.tight_layout()
ax_image.axis('off')

fig.canvas.draw()
xlabel_bbox = ax.xaxis.get_tightbbox(fig.canvas.get_renderer())
xlabel_bbox = xlabel_bbox.transformed(fig.transFigure.inverted())
bbox1 = ax.get_position().union((ax.get_position(),xlabel_bbox))
bbox2 = ax_image.get_position()
bbox3 = mtrans.Bbox.from_bounds(bbox2.x0, bbox1.y0, bbox2.width, bbox1.height)
ax_image.set_position(bbox3)

plt.show()

Изображение 174551

Сохраняя постоянный аспект, вы можете позволить увеличить масштаб изображения в направлении ширины. Это имеет недостаток, что он может накладывать правильные оси или превышать фигуру слева.

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import matplotlib.transforms as mtrans

fig, (ax_image, ax) = plt.subplots(ncols=2, figsize=(8,3))

ax_image.imshow(mpimg.imread('https://matplotlib.org/_images/stinkbug.png'))
ax.plot([0,1],[2,3])
ax.set_ylabel("y")
xlabel = ax.set_xlabel("want image flush with bottom of this label")
fig.tight_layout()
ax_image.axis('off')

fig.canvas.draw()
xlabel_bbox = ax.xaxis.get_tightbbox(fig.canvas.get_renderer())
xlabel_bbox = xlabel_bbox.transformed(fig.transFigure.inverted())
bbox1 = ax.get_position().union((ax.get_position(),xlabel_bbox))
bbox2 = ax_image.get_position()
aspect=bbox2.height/bbox2.width
bbox3 = mtrans.Bbox.from_bounds(bbox2.x0-(bbox1.height/aspect-bbox2.width)/2., 
                                bbox1.y0, bbox1.height/aspect, bbox1.height)
ax_image.set_position(bbox3)

plt.show()

Изображение 174551

Ещё вопросы

Сообщество Overcoder
Наверх
Меню