Plot semi transparent contour plot over image file using matplotlib
You basically need to do two things, set the extent of the image you want in the background. If you dont, the coordinates are assumed to be pixel coordinates, in this case 0 till 600 for both x and y. So adjust you imshow
command to:
implot = subplot1.imshow(pyplot.imread(r'test.png'), interpolation='nearest',
alpha=0.5, extent=[-2500.0,2500.0,-2500.0,2500.0])
If you want to stretch the image to the limits of the plot automatically, you can grab the extent with:
extent = subplot1.get_xlim()+ subplot1.get_ylim()
And pass it to imshow
as extent=extent
.
Since its the background image, setting the alpha to 0.5 makes it very faint, i would set it to 1.0.
Secondly, you set the alpha of the contour lines, but you probably also (or especially) want to set the alpha of the filled contours
. And when you use alpha with filled contours, enabling anti-aliasing reduces artifacts. So change your contourf
command to:
pp = pyplot.contourf(x,y,z,levels=levels,cmap=cmap, alpha=.5, antialiased=True)
And since you already create the subplot object yourself, i would advice also using it to do the plotting instead of the pyplot
interface, which operates on the currently active axes.
So:
subplot1.contourf()
etc
Instead of:
pyplot.contourf()
With the two changes mentioned above, my result looks like:
HotDogCannon
Updated on June 17, 2022Comments
-
HotDogCannon almost 2 years
I'd like to plot a transparent contour plot over an image file in matplotlib/pyplot.
Here's what I got so far...
I have a 600x600 pixel square image file
test.png
that looks like so:I would like to plot a contour plot over this image (having the image file be 'below' and a semi-transparent version of the contour plot overlaid) using matplotlib and pyplot. As a bonus, the image would be automatically scaled to fit within the current plotting boundaries. My example plotting script is as follows:
from matplotlib import pyplot from matplotlib.ticker import MultipleLocator, FormatStrFormatter from matplotlib.colors import BoundaryNorm from matplotlib.ticker import MaxNLocator from pylab import * import numpy as np import random # ----------------------------- # dx, dy = 500.0, 500.0 y, x = np.mgrid[slice(-2500.0, 2500.0 + dy, dy),slice(-2500.0, 2500.0 + dx, dx)] z = [] for i in x: z.append([]) for j in y: z[-1].append(random.uniform(80.0,100.0)) # ----------------------------- # plot_aspect = 1.2 plot_height = 10.0 plot_width = int(plot_height*plot_aspect) # ----------------------------- # pyplot.figure(figsize=(plot_width, plot_height), dpi=100) pyplot.subplots_adjust(left=0.10, right=1.00, top=0.90, bottom=0.06, hspace=0.30) subplot1 = pyplot.subplot(111) # ----------------------------- # cbar_max = 100.0 cbar_min = 80.0 cbar_step = 1.0 cbar_num_colors = 200 cbar_num_format = "%d" # ---------- levels = MaxNLocator(nbins=cbar_num_colors).tick_values(cbar_min, cbar_max) cmap = pyplot.get_cmap('jet') norm = BoundaryNorm(levels, ncolors=cmap.N, clip=True) pp = pyplot.contourf(x,y,z,levels=levels,cmap=cmap) cbar = pyplot.colorbar(pp, orientation='vertical', ticks=np.arange(cbar_min, cbar_max+cbar_step, cbar_step), format=cbar_num_format) cbar.ax.set_ylabel('Color Scale [unit]', fontsize = 16, weight="bold") # ---------- CS = pyplot.contour(x,y,z, alpha=0.5) # ---------- majorLocator1 = MultipleLocator(500) majorFormatter1 = FormatStrFormatter('%d') minorLocator1 = MultipleLocator(250) subplot1.xaxis.set_major_locator(majorLocator1) subplot1.xaxis.set_major_formatter(majorFormatter1) subplot1.xaxis.set_minor_locator(minorLocator1) pyplot.xticks(fontsize = 16) pyplot.xlim(-2500.0,2500.0) # ---------- majorLocator2 = MultipleLocator(500) majorFormatter2 = FormatStrFormatter('%d') minorLocator2 = MultipleLocator(250) subplot1.yaxis.set_major_locator(majorLocator2) subplot1.yaxis.set_major_formatter(majorFormatter2) subplot1.yaxis.set_minor_locator(minorLocator2) pyplot.yticks(fontsize = 16) pyplot.ylim(-2500.0,2500.0) # ---------- subplot1.xaxis.grid() subplot1.yaxis.grid() # ---------- subplot1.axes.set_aspect('equal') # ---------- pyplot.suptitle('Main Title', fontsize = 24, weight="bold") # ---------- pyplot.xlabel('X [m]', fontsize=16, weight="bold") pyplot.ylabel('Y [m]', fontsize=16, weight="bold") # ---------- implot = subplot1.imshow( pyplot.imread('test.png') , interpolation='nearest', alpha=0.5) # ---------- pyplot.show() #pyplot.savefig("tmp.png", dpi=100) pyplot.close()
...but I'm not getting the result I want... instead I just see the contour plot part. Something like:
What should I do in my code to get what I want?