【问题标题】:How to insert a small image on the corner of a plot with matplotlib?如何使用 matplotlib 在绘图的角落插入小图像?
【发布时间】:2011-04-06 07:01:31
【问题描述】:

我想要的非常简单:我有一个名为“logo.png”的小图像文件,我想将其显示在绘图的左上角。但是您在 matplotlib 示例库中找不到任何示例。

我正在使用 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

【问题讨论】:

    标签: python django image matplotlib


    【解决方案1】:

    如果您希望图像位于实际图形的角落(而不是轴的角落),请查看figimage

    也许是这样的? (使用 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()
    

    另一个选项,如果您想让图像成为图形宽度/高度的固定比例,则创建一个“虚拟”轴并将图像与imshow 一起放置在其中。这样图像的大小和位置就独立于 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()
    

    【讨论】:

    • 有没有办法让这个标志相对于右下角定位?
    • @Jared - 尝试以下方式:fig.figimage(im, fig.bbox.xmax - width, height)
    • 有没有dpi独立图片放置的方法?
    • @tillsten - 有几种不同的方法,但它们都是 hackish。你想要什么独立于 dpi,图像的大小,它的位置,或两者兼而有之?如果两者兼而有之,一个方便的技巧是创建一个新轴(手动指定其位置和大小),使用imshow,并使用axis('off') 关闭刻度等。各种OffsetImage 功能是另一种方式,但是如果你走那条路,尺寸不是独立于 dpi 的。
    • @tillsten - 实际上,现在我想起来了,如果您只想以独立于 dpi 的方式将图像放置在另一个角落,那么有一个更简单的方法。我会用一个例子来更新答案。
    【解决方案2】:

    现在有一个更简单的方法,使用新的inset_axes 命令(需要matplotlib >3.0)。

    此命令允许将一组新轴定义为现有axes 对象的子级。这样做的好处是您可以使用适当的transform 表达式以您喜欢的任何单位定义插入轴,例如轴分数或数据坐标。

    下面是一个代码示例:

    # 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')
    

    这种方法的优点是您的图像会随着您的坐标轴重新缩放而自动缩放!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      • 1970-01-01
      • 2014-11-19
      • 2021-06-06
      • 1970-01-01
      相关资源
      最近更新 更多