Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
181 views
in Technique[技术] by (71.8m points)

python - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...