Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib Pyplot logo/image in Plot

I'm struggling to achieve a simple goal in matplotlib... I want to put a small logo or indicator in the bottom right of my graph, without altering the axis or the real data that is being displayed. Here is my code now:

fig = plt.figure()
plt.rcParams.update({'font.size': 15})

img = plt.imread('./path/to/image.png')
ax1 = fig.add_subplot(111)
ax1.yaxis.tick_left()
ax1.tick_params(axis='y', colors='black', labelsize=15)
ax1.tick_params(axis='x', colors='black', labelsize=15)

plt.grid(b=True, which='major', color='#D3D3D3', linestyle='-')

plt.scatter([1,2,3,4,5],[5,4,3,2,1], alpha=1.0)

plt.autoscale(enable=True, axis=u'both')

fig.savefig('figure.png')

My output from this is below.

This is now laying the photo over the whole graph -- I'd like it scaled to 20% of width & height (if possible) and anchored to the bottom right. This also ruins my axis, because in this output I should be in the 0-100 range on both x & y. Any ideas to solve this, the scaling is the big issue.

Edit1: I've tried the solution below and linked questions here on SO. The problem is relying on the extent variable being passed to imshow() then doesn't work well when introducing new data. For example plotting a scatter plot coming from a data frame, could be from 0..1000 and 50..100 but using extent won't show the label or the position will be off.

Edit2: There seems to be some progress with getting the figure length with fig.get_size_inches() and passing the variable to extent. Apparently all of matplotlib graph calculations are done through inches, so this may be a promising lead.

enter image description here

like image 729
Jared Avatar asked Apr 09 '15 20:04

Jared


2 Answers

import matplotlib.image as image
import matplotlib.pyplot as plt

im = image.imread('debian-swirl.png')
fig, ax = plt.subplots()
ax.imshow(im, aspect='auto', extent=(0.4, 0.6, .5, .7), zorder=-1)
ax.yaxis.tick_left()
ax.tick_params(axis='y', colors='black', labelsize=15)
ax.tick_params(axis='x', colors='black', labelsize=15)
ax.grid(b=True, which='major', color='#D3D3D3', linestyle='-')
ax.scatter([1,2,3,4,5],[5,4,3,2,1], alpha=1.0)
plt.show()

enter image description here

I added a png file to bottom left. Adjust the extent parameter to set the logo position.

Similar to : Scale image in matplotlib without changing the axis

like image 53
Kirubaharan J Avatar answered Oct 10 '22 12:10

Kirubaharan J


The following is an adaptation of the answer by Kirubaharan J, but adapting the position of the logo to the extent of the graph (but the aspect ratio of the logo itself is not preserved)

import matplotlib.image as image
import matplotlib.pyplot as plt

im =image.imread('debian-swirl.png')
fig, ax = plt.subplots()
ax.yaxis.tick_left()
ax.tick_params(axis='y', colors='black', labelsize=15)
ax.tick_params(axis='x', colors='black', labelsize=15)
ax.grid(b=True, which='major', color='#D3D3D3', linestyle='-')
ax.scatter( [100,90,89,70], [55, 23,76,29], alpha=1.0)

plt.autoscale(enable=True, axis=u'both')

xrng=plt.xlim()
yrng=plt.ylim()
scale=.2 #the image takes this fraction of the graph
ax.imshow(im,aspect='auto',extent=(xrng[0],xrng[0] + scale*(xrng[1]-xrng[0]), yrng[0], yrng[0] + scale*(yrng[1]-yrng[0]) ), zorder=-1)
plt.xlim(xrng)
plt.ylim(yrng)

plt.show()
like image 41
Frédéric Grosshans Avatar answered Oct 10 '22 14:10

Frédéric Grosshans