0

How do you add a Background Image on a scatter plot with loglog axes? My problem is that the background image is also rescaled in log style which I don't want.

ax3 = fig2.add_subplot(1, 1, 1)
pathimage=directory+'\Robertson.PNG'
img = mpimg.imread(directory+'\Robertson.PNG')  
ax3.scatter(rf_layer,qc_layer)
ax3.set_title(filename, y=1.1,fontsize=12)
ax3.set_yscale('log')
ax3.set_xscale('log')
ax3.legend(Legend,loc=9, bbox_to_anchor=(0.5, -0.2),ncol=len(layerdepth))
ax3.set_ylim([1, 100])
ax3.set_xlim([0.1, 10])
ax3.set_xlabel('Rf in %')
ax3.set_ylabel('qc in MPa')          
ax3.imshow(img,extent=[0.1,10,1,100])

1 Answers1

2

You can do this with a twin Axes, which is not set to loglog scale. In this case, we want to make both twin x and y axes, so we can stack the commands, as shown here:

ax4 = ax3.twinx().twiny()

An alternative is to just create a new Axes instance in the same position as the first (from @ImportanceOfBeingErnest in the comments). For example:

ax4 = fig.add_subplot(111, label="ax4")

We also need to make ax3 transparent so we can see through it to the image below (facecolor='None').

We also need to set the zorder to ax3 is on top of ax4.

Here is a working example:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

# Dummy data
rf_layer = 0.1 + np.random.rand(20) * 9.9
qc_layer = 1. + np.random.rand(20) * 99.

fig2 = plt.figure()

# Make ax3 transparent so we can see image behind
ax3 = fig2.add_subplot(1, 1, 1, facecolor='None')

pathimage='./stinkbug.png'
img = mpimg.imread(pathimage)

ax3.scatter(rf_layer, qc_layer)
ax3.set_title('my title', y=1.1, fontsize=12)
ax3.set_yscale('log')
ax3.set_xscale('log')
ax3.set_ylim([1, 100])
ax3.set_xlim([0.1, 10])
ax3.set_xlabel('Rf in %')
ax3.set_ylabel('qc in MPa')          

# Create second axes
ax4 = ax3.twinx().twiny()

# Or alternatively
# ax4 = fig.add_subplot(111, label="ax4")

# Add image to twin axes
ax4.imshow(img)

# Fix zorder so ax3 on top of ax4
ax3.set_zorder(10)
ax4.set_zorder(1)

# Turn off ticks from twin axes
ax4.set_yticks([])
ax4.set_xticks([])

plt.show()

enter image description here

tmdavison
  • 64,360
  • 12
  • 187
  • 165
  • May I suggest not to use twin axes, but rather a completely new axes, `ax4 = fig.add_subplot(111, label="ax4")` – ImportanceOfBeingErnest Jan 14 '19 at 12:04
  • Do u know how to set up an image like that as a background for a scatterplot in seaborn? I am trying but I can not find any solution. – Hip Jul 31 '22 at 21:00
  • seaborn just uses matplotlib to do the plotting; so if you get a reference to the axes it is plotting on, you can use any matplotlib functions you like on there too: in this case, you would want to use `ax.imshow` once you get your `ax` from seaborn – tmdavison Aug 02 '22 at 08:06