Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib automate placement of watermark

I'm trying to write a function to automate the placement of watermark in the lower right of my figures. Here is my function so far.

from PIL import Image
import matplotlib.pyplot as plt

def watermark(fig, ax):

    """ Place watermark in bottom right of figure. """

    # Get the pixel dimensions of the figure
    width, height = fig.get_size_inches()*fig.dpi

    # Import logo and scale accordingly
    img = Image.open('logo.png')
    wm_width = int(width/4) # make the watermark 1/4 of the figure size
    scaling = (wm_width / float(img.size[0]))
    wm_height = int(float(img.size[1])*float(scaling))
    img = img.resize((wm_width, wm_height), Image.ANTIALIAS)

    # Place the watermark in the lower right of the figure
    xpos = ax.transAxes.transform((0.7,0))[0]
    ypos = ax.transAxes.transform((0.7,0))[1]
    plt.figimage(img, xpos, ypos, alpha=.25, zorder=1)

The problem is that when I add a label to either axis the position of the water mark changes. E.g. adding ax.set_xlabel('x-label', rotation=45) changes the watermark position significantly. This seems to be the case because the placement of the watermark is relative to the whole figure (e.g. the plotting and axis area), however the function get_size_inches() only calculates the plotting area (e.g. not including the axis area).

Is there anyway to get the pixel dimensions of the entire figure (e.g. including axis area) or another easy workaround.

Thanks in advance.

like image 552
jfried Avatar asked Mar 09 '23 03:03

jfried


1 Answers

You may want to use an AnchoredOffsetbox in which you place an OffsetImage. The advantage would be that you can use the loc=4 argument to place the Offsetbox in the lower right corner of the axes (just like in the case of a legend).

from PIL import Image
import matplotlib.pyplot as plt
from matplotlib.offsetbox import ( OffsetImage,AnchoredOffsetbox)


def watermark2(ax):
    img = Image.open('house.png')
    width, height = ax.figure.get_size_inches()*fig.dpi
    wm_width = int(width/4) # make the watermark 1/4 of the figure size
    scaling = (wm_width / float(img.size[0]))
    wm_height = int(float(img.size[1])*float(scaling))
    img = img.resize((wm_width, wm_height), Image.ANTIALIAS)

    imagebox = OffsetImage(img, zoom=1, alpha=0.2)
    imagebox.image.axes = ax

    ao = AnchoredOffsetbox(4, pad=0.01, borderpad=0, child=imagebox)
    ao.patch.set_alpha(0)
    ax.add_artist(ao)

fig, ax = plt.subplots()
ax.plot([1,2,3,4], [1,3,4.5,5])

watermark2(ax)
ax.set_xlabel("some xlabel")
plt.show()

enter image description here

like image 162
ImportanceOfBeingErnest Avatar answered Mar 19 '23 06:03

ImportanceOfBeingErnest