Я пытаюсь построить изображение рядом с некоторыми данными. Тем не менее, я хотел бы, чтобы изображение расширялось, чтобы быть на одном уровне с метками графика. Например, следующий код (используя этот образ учебника):
# 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")
дает этот сюжет с дополнительными пробелами:
Мне нужен сюжет, который не пуст. Следующий взломанный код (в духе этой ссылки 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")
получив следующий рисунок:
Есть ли способ построить изображение на одном уровне с другими подзадачами, не прибегая к ручной настройке размеров фигур?
Вы можете получить объединение ограничивающего прямоугольника правых осей и его метки и установить положение левых осей таким образом, чтобы оно начиналось в вертикальном положении ограничивающего блока объединения. Следующее предполагает некоторый автоматический аспект на изображении, то есть изображение искажается в одном направлении.
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()
Сохраняя постоянный аспект, вы можете позволить увеличить масштаб изображения в направлении ширины. Это имеет недостаток, что он может накладывать правильные оси или превышать фигуру слева.
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()