Put image between custom lines in plot in python

I would like to use the specified functions or strings to create a border for the images, and then put custom images inside the borders.

I used padding between the examples, but there may be an easier way to achieve this. Here is what I mean:

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 this code is the image that I have:

and I would like something like this what I want:

Please keep in mind that I would like to have a border around the image that I can adjust, and if I have more than one fillbetween, I can choose what to place inside different curves. And also, if it is possible to respect the relation of the axis of the image, so that its shape is not distorted when I put it in the graph.

+4
1

, . OffsetImage AnnotationBbox. Patch clip_path . Path, .

enter image description here

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()
+3

Source: https://habr.com/ru/post/1681035/


All Articles