简体   繁体   English

如何使用matplotlib在绘图的角落插入小图像?

[英]How to insert a small image on the corner of a plot with matplotlib?

What I want is really simple: I have a small image file called "logo.png" that I want to display on the upper left corner of my plots.我想要的非常简单:我有一个名为“logo.png”的小图像文件,我想将其显示在绘图的左上角。 But you can't find any example of that in the matplotlib examples gallery.但是您在 matplotlib 示例库中找不到任何示例。

I'm using django, and my code is something like this:我正在使用 django,我的代码是这样的:

def get_bars(request)
    ...
    fig = Figure(facecolor='#F0F0F0',figsize=(4.6,4))
    ...
    ax1 = fig.add_subplot(111,ylabel="Valeur",xlabel="Code",autoscale_on=True)
    ax1.bar(ind,values,width=width, color='#FFCC00',edgecolor='#B33600',linewidth=1)
    ...
    canvas = FigureCanvas(fig)
    response = HttpResponse(content_type='image/png')
    canvas.print_png(response)
    return response

If you want the image at the corner of your actual figure (rather than the corner of your axis), look into figimage .如果您希望图像位于实际图形的角落(而不是轴的角落),请查看figimage

Perhaps something like this?也许像这样? (using PIL to read the image): (使用 PIL 读取图像):

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

im = Image.open('/home/jofer/logo.png')
height = im.size[1]

# We need a float array between 0-1, rather than
# a uint8 array between 0-255
im = np.array(im).astype(np.float) / 255

fig = plt.figure()

plt.plot(np.arange(10), 4 * np.arange(10))

# With newer (1.0) versions of matplotlib, you can 
# use the "zorder" kwarg to make the image overlay
# the plot, rather than hide behind it... (e.g. zorder=10)
fig.figimage(im, 0, fig.bbox.ymax - height)

# (Saving with the same dpi as the screen default to
#  avoid displacing the logo image)
fig.savefig('/home/jofer/temp.png', dpi=80)

plt.show()

替代文字

Another option, if you'd like to have the image be a fixed fraction of the figure's width/height is to create a "dummy" axes and place the image in it with imshow .另一种选择,如果您想让图像成为图形宽度/高度的固定分数,则创建一个“虚拟”轴并使用imshow将图像放入其中。 This way the image's size and position is independent of DPI and the figure's absolute size:这样图像的大小和位置就独立于 DPI 和图形的绝对大小:

import matplotlib.pyplot as plt
from matplotlib.cbook import get_sample_data

im = plt.imread(get_sample_data('grace_hopper.jpg'))

fig, ax = plt.subplots()
ax.plot(range(10))

# Place the image in the upper-right corner of the figure
#--------------------------------------------------------
# We're specifying the position and size in _figure_ coordinates, so the image
# will shrink/grow as the figure is resized. Remove "zorder=-1" to place the
# image in front of the axes.
newax = fig.add_axes([0.8, 0.8, 0.2, 0.2], anchor='NE', zorder=-1)
newax.imshow(im)
newax.axis('off')

plt.show()

在此处输入图片说明

There is now a much easier way, using the new inset_axes command (matplotlib >3.0 required).现在有一个更简单的方法,使用新的inset_axes命令(需要 matplotlib >3.0)。

This command allows one to define a new set of axes as a child of an existing axes object.此命令允许将一组新轴定义为现有axes对象的子项。 The advantage of this is that you can define your inset axes in whatever units you please, like axes fraction or data coordinates, using the appropriate transform expression.这样做的好处是您可以使用适当的transform表达式以任何您喜欢的单位定义插入轴,例如轴分数或数据坐标。

So here's a code example:所以这是一个代码示例:

# Imports
import matplotlib.pyplot as plt
import matplotlib as mpl

# read image file
with mpl.cbook.get_sample_data(r"C:\path\to\file\image.png") as file:
arr_image = plt.imread(file, format='png')

# Draw image
axin = ax.inset_axes([105,-145,40,40],transform=ax.transData)    # create new inset axes in data coordinates
axin.imshow(arr_image)
axin.axis('off')

The advantage of this method is that your image will scale automatically as your axes get rescaled!这种方法的优点是您的图像将在您的轴重新缩放时自动缩放!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM