Я пробовал различные методы, найденные в Интернете, но не смог добавить изображение в правильное место в верхнем левом углу фигуры.
Вот одна из моих попыток, где я пытаюсь установить точный размер сгенерированной фигуры в пикселях, а затем добавляю изображение размером 48x48 пикселей в верхний левый угол. Проблемы:
Почему приведенный ниже код не работает? Как я могу достичь того, чего хочу?
import matplotlib.pylab as plt # Plot
from PIL import Image # Add background image
from matplotlib.offsetbox import AnnotationBbox, OffsetImage # Add background image
def plot_image(w, h):
px = 1/plt.rcParams['figure.dpi']
fig,ax = plt.subplots(figsize=(w*px, h*px))
image_path = '......../The Simpsons 48x48.png'
image_data = Image.open(image_path)
image_box = OffsetImage(image_data, zoom=1)
anno_box = AnnotationBbox(image_box, xy=(34,h-48), xycoords='figure pixels', frameon=False)
ax.add_artist(anno_box)
plt.text(0.5, 0.5, f'Requested: {w}x{h}')
plt.text(0.5, 0.4, 'Obtained: 579x455' if w==640 else
'Obtained: 759x561' if w==800 else
'Obtained: 960x711' )
plt.show()
plot_image( 640, 480)
plot_image( 800, 600)
plot_image(1024, 768)
Полученные результаты:
Использованное изображение:






Все дело в понимании размера изображения. Сначала убедитесь, что размер фигуры установлен правильно в пикселях, а затем правильно поместите изображение в верхний левый угол, используя AnnotationBbox. Вот как вам следует это сделать:
import matplotlib.pyplot as plt
from PIL import Image
from matplotlib.offsetbox import AnnotationBbox, OffsetImage
def plot_image(w, h):
px = 1 / plt.rcParams['figure.dpi']
fig, ax = plt.subplots(figsize=(w * px, h * px))
image_path = r"C:\Users\serge.degossondevare\Downloads\homer.png"
image_data = Image.open(image_path)
image_box = OffsetImage(image_data, zoom=1)
anno_box = AnnotationBbox(image_box, xy=(0, 1), xycoords='axes fraction',
box_alignment=(0, 1), frameon=False)
ax.add_artist(anno_box)
plt.text(0.5, 0.5, f'Requested: {w}x{h}', ha='center', va='center')
plt.text(0.5, 0.4, f'Obtained: {int(fig.bbox.width)}x{int(fig.bbox.height)}', ha='center', va='center')
ax.set_axis_off()
plt.show()
plot_image(640, 480)
plot_image(800, 600)
plot_image(1024, 768)
что дает вам
Если вы хотите, чтобы изображение Гомера было пропорционально уменьшено до холста:
import matplotlib.pyplot as plt
from PIL import Image
from matplotlib.offsetbox import AnnotationBbox, OffsetImage
def plot_image(w, h, image_path):
px = 1 / plt.rcParams['figure.dpi']
fig, ax = plt.subplots(figsize=(w * px, h * px))
image_data = Image.open(image_path)
zoom_factor = min(w / image_data.width, h / image_data.height) * 0.1
image_box = OffsetImage(image_data, zoom=zoom_factor)
anno_box = AnnotationBbox(image_box, xy=(0, 1), xycoords='axes fraction',
box_alignment=(0, 1), frameon=False)
ax.add_artist(anno_box)
plt.text(0.5, 0.5, f'Requested: {w}x{h}', ha='center', va='center')
plt.text(0.5, 0.4, f'Obtained: {int(fig.bbox.width)}x{int(fig.bbox.height)}', ha='center', va='center')
ax.set_axis_off()
plt.show()
image_path = r"C:\Users\serge.degossondevare\Downloads\homer.png"
plot_image(640, 480, image_path)
plot_image(800, 600, image_path)
plot_image(1024, 768, image_path)
который дает
Тогда масштабирование зависит от вас.
Тогда вам следует опубликовать то, что вы ожидаете.
Извините за форматирование. Я понятия не имею, как форматировать ответ. Если форматирование вообще возможно.
Я обновил альтернативу, которая пропорционально масштабируется по холсту.
К сожалению, обновление по-прежнему не создает изображения с ожидаемым разрешением и не выравнивает края.
Также Гомер, кажется, добавлен размером примерно 85x85 пикселей.
Хорошо, похоже, проблема в том, что моя IDE некорректно отображает сгенерированные изображения, как указал RuthC. Какую IDE вы используете, где не нужно сохранять изображение для его корректного просмотра?
@Chris Я думаю, что у Сержа та же проблема: если вы проверите изображения, размещенные в этом ответе, они не будут иметь правильный размер.
Да, именно это я и пытался подчеркнуть, предоставив HTML-код графиков, загруженных Сержем. Использование AnnotationBbox неправильно позиционирует изображение и неправильно определяет размер вставленного изображения. Очень обидно для такой зрелой библиотеки. И очень разочаровывает то, что среды разработки Python не могут даже правильно отображать созданные изображения. Кажется, это такая базовая функция.
Вы пользуетесь блокнотом? Когда вы показываете в блокноте, размер фигуры автоматически изменяется, чтобы соответствовать изображенным на ней художникам. Это эквивалентно передаче bbox_inches='tight' при вызове savefig . Это можно отключить в блокноте, но я только что попробовал заменить plt.show() в вашем примере на plt.savefig(f'simpson_test{w}x{h}.png'), и все они получились нужного размера.
Я не понял, почему позиционирование у AnnotationBbox странное, но есть более простой способ figimage:
import matplotlib.pyplot as plt # Plot
from PIL import Image # Add background image
def plot_image(w, h):
px = 1/plt.rcParams['figure.dpi']
fig,ax = plt.subplots(figsize=(w*px, h*px))
image_path = 'simpson.png'
image_data = Image.open(image_path)
fig.figimage(image_data, yo=h-48)
plt.text(0.5, 0.5, f'Requested: {w}x{h}')
plt.savefig(f'simpson_test{w}x{h}.png')
plot_image( 640, 480)
plot_image( 800, 600)
plot_image(1024, 768)
Я использую VS Code. Что ты используешь? Я пробовал использовать PyCharm, но он не находит библиотеки, импортирующие matplotlib.pylab как plt # Plot ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ModuleNotFoundError: нет модуля с именем matplotlib.
Гррр. VS Code не только неправильно отображает размер, но и не может правильно позиционировать Гомера.
Хорошо, я переустановил matplotlib из PyCharm (зачем мне это делать?). Когда я запускаю код, он открывает окно под названием «Рисунок 1», в котором также отображается совершенно ошибочное изображение. Эти инструменты кажутся такими древними и простыми. Не можете даже правильно отобразить картинку? Действительно? Напоминает мне времена, когда единственным возможным результатом работы мэйнфрейма была бумага. :-( Любая IDE Python, которая может правильно отображать изображения? Теперь PyCharm может запускать мой код, но не ваш. Gtk-Message: 12:49:45.182: Не удалось загрузить модуль «xapp-gtk3-module»
figimage(), похоже, отлично справляется со своей задачей. Спасибо. Не могу поверить, что потратил все это время на создание изображения, которое не соответствует реальному результату. Я проведу еще несколько тестов и отмечу ваш повтор как ответ.
Боюсь, я на самом деле не использую IDE, а просто запускаю свои скрипты из командной строки.
Я только сейчас заметил, что в этом примере используется pylab. Это не рекомендуется, поэтому я обновил импорт для использования pyplot.
Спасибо. Мне еще предстоит многое узнать об этом AnnotationBbox. Однако: <br/> 1. Изображения выше не соответствуют ожиданиям. Размер сбился. <img src = "i.sstatic.net/Ol7hMw81.png " alt = " i.sstatic.net/Ol7hMw81.png" width = "627" height = "474" class = "shrinkToFit"> для изображения 800x600. <br/> 2- Вставленное изображение не выровнено.