在python中的绘图中的自定义行之间放置图像 [英] Place an image between custom lines in a plot in python

查看:602
本文介绍了在python中的绘图中的自定义行之间放置图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要的是使用指定的函数或线来创建图像的边框,然后在边框内放置自定义图像。

What I would like is to use specified functions or lines to create the border of the images, and then inside the borders place custom images.

我用之间填充作为一个例子,但也许有一种更简单的方法来实现这一目标。这就是我的想法:

I used fill between as an example, but maybe there is an easier way of achieving this. This is what I have in mind:

import matplotlib.pyplot as plt
import numpy as np

x   = np.linspace(0,100,1000)
y   = (3 + np.sin(x/5.)) * np.exp(-abs(x-50)/25.)*10

x2  = np.linspace(20,40,1000)
y2  = np.sqrt(100 - (x2 - 30)**2) + 40
y3  = -np.sqrt(100 - (x2 - 30)**2) + 40

plt.figure()
ax1 = plt.subplot(1,1,1, aspect='equal')
plt.fill_between(x=x, y1=y, y2=0,  alpha=0.5, color='orange', linewidth=3)
plt.fill_between(x=x2, y1=y2, y2=y3,  alpha=0.5, color='green', linewidth=3)
ax1.axis('off')

该代码的输出是这张图片,我有:

the output of that code is this image, what I have:

我想要这样的东西,我想要的东西:

and I would like something like this, what I want:

请进来我想在ima周围有一个边框我可以自定义它,如果我有多个填充,我可以选择放入不同曲线的内容。
并且如果它可以尊重图像的轴比例,那么当我将它放在图中时它的形状不会变形。

Please have in mind that I would like to have a border around the image that I can customize it, and if I have more than one fillbetween, I can choose what to put inside the different curves. And also if its possible to respect the axis ratio of the image so its shape doesn't get distorted when I place it in the plot.

推荐答案

有很多不同的方法可以获得剪裁成某种形状的图像。我个人喜欢在 AnnotationBbox 中使用 OffsetImage 。在下面的解决方案中, Patch 用作图像的 clip_path 。如果函数的输入是 Path ,则首先将其转换为补丁。

There are a lot of different ways to obtain an image clipped to some shape. I personally like to use of an OffsetImage inside an AnnotationBbox. In the solution below a Patch is used as a clip_path for the image. If the input to the function is a Path, it is converted to a patch first.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch
from matplotlib.offsetbox import OffsetImage, AnnotationBbox


plt.figure()
ax1 = plt.subplot(1,1,1, aspect='equal')
ax1.axis('off')

def img_to_path( fn, path, zoom=0.72, ax = None, **kwargs):
    if ax==None: ax=plt.gca()
    kwargs.pop("facecolor", None)
    im = plt.imread(fn, format='png')
    if type(path) == Path:
        xmin = path.vertices[:,0].min()
        ymin = path.vertices[:,1].min()
        patch = PathPatch(path, facecolor='none', zorder=3, **kwargs)
    else:
        patch = path
        xmin = patch.get_verts()[:,0].min()
        ymin = patch.get_verts()[:,1].min()

    ax.add_patch(patch)
    imagebox = OffsetImage(im, zoom=zoom, clip_path=patch, zorder=-10)
    boxoffset = np.array(im.shape[:2][::-1])/2.*zoom
    ab = AnnotationBbox(imagebox, (xmin,ymin), xycoords='data',
                        xybox=boxoffset, boxcoords="offset points", 
                        pad=0, frameon=False)
    ax.add_artist(ab)

# two images
fn1 = "data/raspberries.png"
fn2 = "data/blueberries.png"

# use a Path 
x   = np.linspace(0,100,1000)
y   = (3 + np.sin(x/5.)) * np.exp(-abs(x-50)/25.)*10
x = np.append(x,[x[-1],x[0], x[0]])
y = np.append(y,[0,0,y[0]])
path = Path(np.c_[x,y], [1]+[2]*(len(x)-2)+[79])
img_to_path(fn1, path, edgecolor="red", lw=4, ax=ax1 )

# use a Patch
circ = plt.Circle((30,40), 10, edgecolor="gold", lw=13, zorder=3 )
img_to_path(fn2, circ, zoom=0.15, ax=ax1 )


ax1.relim()
ax1.autoscale_view()
plt.show()

这篇关于在python中的绘图中的自定义行之间放置图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆