Generating Heatmaps from pixel coordinates - python

I have a set of pixel values that I wanted to map on an image as a heatmap. My pixel values look something like this: they are x,y coordinates of image pixels of an arbitrary resolution.
pixel values = [[1,1],[2,1],[3,1],[4,1],[2,1]]
I have tried using OpenCV but I fail to understand how to get it to work. I assume a probability/density distribution needs to be generated, or perhaps the plotting function can do this automatically ? Since the image is loaded using OpenCV, I was looking for an OpenCV function, if Matplotlib works, please do comment.
heatmap_array = np.array(heatmap)
cv_colormap = cv2.applyColorMap(heatmap_array[0:], cv2.COLORMAP_HOT)
cv2.imwrite("colormap_gen.jpg", cv_colormap)
There needs to be an slightly opaque overlay of the heatmap on top of the original image.

You can try with Matplotlib:
# sample data
# xy can be np.array(pixel_values)
np.random.seed(1)
xy = np.random.multivariate_normal([300,300], [[2000,400],[400,1000]], 2000000)
# compute the hist
# bins here are the size of the image
hist,_,_ = np.histogram2d(xy[:,0], xy[:,1], bins=(600,800))
# show heatmap by plt
# you can use plt to save the figure
fig = plt.figure(figsize=(12,8))
plt.imshow(hist,cmap='hot')
plt.axis('off')
plt.show()
Output:

Related

Plotting a scatter plot on an image Python

I have plotted some data that are defined by specific coordinates and a value.
I have plotted this with a scatterplot, and would now like to plot this on top of an image, to reflect where the data points are located.
I have tried to use matplotlib.image and import img to be able to show the image. Unfortunately, the image of my location does not match up with the data completely (due to stretching, I believe).
When I edit the extent Python either edits out some of the image, instead of moving my data. I would like to be able to move the image/crop it to fit with the data or use some sort of package to load in a map (as I have the coordinates). This needs to show a local stream in Denmark.
x and y are our coordinates (lat, lon) and z is the value each coordinate have.
plt.figure(figsize=(20,10))
plt.scatter(x,y, cmap = 'gist_heat' ,s=100,c=z)
plt.colorbar()
plt.ylim(np.min(y),np.max(y))
plt.xlim(np.min(x),np.max(x))
img = plt.imread("grindsted4_sattelit.png")
ext = [np.min(x),np.max(x), np.min(y), np.max(y)]
plt.imshow(img, zorder=0, extent=ext)
aspect=img.shape[0]/float(img.shape[1])*((ext[1]-ext[0])/(ext[3]-ext[2]))
plt.gca().set_aspect(aspect)
plt.show()
The plot are the colored dots, and the black and white dots are my coordinates in Google Earth.
Thank you!

How to modify some axis' attribute with an image in python?

I have an image in python. It's a map of california, and I need to place some point on this map.
The coordonate of each point are retrieve from a csv. But the value of each coordinate are in latitude/longitude. So, i need to convert it to the dimension of my picture.
So, here's is the description of my situation:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
# dpi for the saved figure: https://stackoverflow.com/a/34769840/3129414
dpi = 120
img = mpimg.imread("california_map_blank.png")
height, width, bands = img.shape
# Update figure size based on image size
figsize = width / float(dpi), height / float(dpi)
# Create a figure of the right size with one axes that takes up the full figure
figure = plt.figure(figsize=figsize)
axes = figure.add_axes([0, 0, 1, 1])
# Draw the image
axes.imshow(img, interpolation='nearest')
Here's the result:
First i need to modify the y-axis. I need to inverse it so the 0 start at the bottom. Then I need to modify the value of the axis, [31,42] for y-axis and [-123,-114] for x-axis. Because the point I want to place in this map are all in this range. One example of coordinate: 41.76440000093729, -124.1998.
Now here's my question. Is it possible to achieve this ? How ?
PS: I use python 3.6, and I already know how to place point on the image. I don't need to save the image just showing.
PPS: My final goal in fact is to convert lat/lon data into coordinate in a picture so if you know any other way to do it(in Python of course) please tell me.
EDIT: If I apply this: axes.set_xlim(-124.5,-114) it give me this:
I want to have the axis with this range but with the whole image.
In fact, at the end I will not display the axis I will just put the map with the points, but I need to place the point on the map so I think I need to go through this step.
EDIT2: I tried this: axes.imshow(img[::-1], origin='lower', interpolation='nearest') it works fine to reverse the axis but when I draw a point python draw it in the same place when I the axis was normal.
You need to set the limits of the image via the extent= parameter of imshow. These should be quite precise values for the longitudes left and right, and for the latitudes of bottom and top.
Depending on how deformed the map is, the result can be good enough or not. Try to find the exact longitudes and latitudes of the corners of your map, e.g. via Google Maps.
Depending on how you're running your Python program, matplotlib will show an interactive plot. You can zoom to every region, and the axes will adapt. In the bar at the bottom the x and y-positions will be shown. If they are not the desired ones, you can try to change the extents until they match.
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
img = mpimg.imread("california_map_blank.png")
dpi = 120
height, width, bands = img.shape
# Update figure size based on image size
figsize = width / float(dpi), height / float(dpi)
# Create a figure of the right size with one axes that takes up the full figure
fig, ax = plt.subplots(figsize=figsize)
# find the extent
longitude_top_left = -124.5
longitude_top_right = -113
latitude_bottom_left = 32
latitude_top_left = 42
extent = [longitude_top_left, longitude_top_right, latitude_bottom_left, latitude_top_left]
# Draw the image
ax.imshow(img, interpolation='nearest', extent=extent)
plt.show()

How do I add a colorbar to an image while saving it?

I have a 2 dimensional matrix, say img which I want to save as in image, using the 'hot' colormap. The following code
import matplotlib.pyplot as plt
plt.imsave("out.jpg", img, cmap = 'hot')
allows me to do this. However, I want to save the colorbar along with the image, it is important for me to know what the value at each pixel was, roughly. Let's assume that I have a lot of space available on the right.
I know that it can be done in an "easy" way, by creating a figure using plt.imshow(), adding a colorbar using plt.colorbar() and then saving it using plt.savefig(), but that also saves the "grey region" around the figure and the colorbar appears separately. Also, this has issues with the figure size, in case scaling is involved. I want the colorbar to appear ON the image, and the resultant output image to be of the same size as the matrix.
Also, if anyone has any other suggestions about visualizing a matrix as an image, (where the values are not bounded), they would be appreciated.
I'm not sure how to add a colorbar to your image before you save it like you want to, and I'm not even sure if that's possible. But I can provide you with a way to plot your image, add the colorbar, and save it, but format it the way you want. Try something like the following
import matplotlib.pyplot as plt
fig = plt.figure(figsize = (W,H)) # Your image (W)idth and (H)eight in inches
# Stretch image to full figure, removing "grey region"
plt.subplots_adjust(left = 0, right = 1, top = 1, bottom = 0)
im = plt.imshow('out.jpg') # Show the image
pos = fig.add_axes([0.93,0.1,0.02,0.35]) # Set colorbar position in fig
fig.colorbar(im, cax=pos) # Create the colorbar
plt.savefig('out.jpg')
I can't guarantee that this will work without having something to test it on, but it should be in the right direction for what you want.

python matplotlib, get pixel value after colormap applied

I display an image with matplotlib using imshow().
imshow apply a LUT and I would like to retrieve a pixel value (at x, y) after LUT applied.
For exemple
I have a full black image
I display with imshow
The image becomes yellow (cause of LUT)
get_pixel(x, y) -> yellow
Is there a way to code the function get_pixel ?
So, to get to the color of pixels, you have to look at how matplotlib maps the scalar values of the pixels to colors:
It is a two step process. First, a normalization is applied to map the values to the interval [0,1]. Then, the colormap maps from [0,1] to colors. For both steps matplotlib provides various options.
If you just call imshow it will apply the a basic linear normalization using the minimum and maximum of your data. The normalization class instance is then saved as an attribute of the artist. The same thing holds for the colormap.
So to compute the color of a specific pixel you have to apply these two steps manually:
import matplotlib.pyplot as plt
import numpy as np
# set a seed to ensure reproducability
np.random.seed(100)
# build a random image
img = np.random.rand(10,10)
# create the image and save the artist
img_artist = plt.imshow(img, interpolation='nearest')
# plot a red cross to "mark" the pixel in question
plt.plot(5,5,'rx', markeredgewidth=3, markersize=10)
# get the color at pixel 5,5 (use normalization and colormap)
print img_artist.cmap(img_artist.norm(img[5,5]))
plt.axis('image')
plt.show()
Result:
And the color:
(0.0, 0.84901960784313724, 1.0, 1.0)

matplotlib imshow how to plot points instead of image?

Here is the code:
plots=imshow(Z,extent=extent,origin,cmap=cmap,aspect='auto',vmin=vmin,vmax=vmax)
plots.plot(Response,component,vrange)
It plots an image based on data list Z, how can I let it print data points instead of an image?
Looks like needs to change to scatter(x, y,...) to plot data points, how difficult it is to change array Z to x, y?
As #jdj081 said, you want to produce a scatter plot.
import os.path
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
# get an image from the sample data directory
fname = os.path.join(matplotlib.get_data_path(), 'sample_data', 'lena.png')
im = plt.imread(fname)
# Reduce the data by a factor of 4 (so that we can see the points)
im = im[::4, ::4]
# generate coordinates for the image. Note that the image is "top down", so the y coordinate goes from high to low.
ys, xs = np.mgrid[im.shape[0]:0:-1, 0:im.shape[1]]
# Scatter plots take 1d arrays of xs and ys, and the colour takes a 2d array,
# with the second dimension being RGB
plt.scatter(xs.flatten(), ys.flatten(), s=4,
c=im.flatten().reshape(-1, 3), edgecolor='face')
plt.show()
You didn't provide much information to go on, but it sounds like you really want to create a scatter plot.
There are many options here depending on what you are plotting and what you want to see, but I have found the following helpful:
Fixing color in scatter plots in matplotlib
import pylab
pylab.figure(1)
pylab.plot([1,2,3,4],[1,7,3,5]) # draw on figure one
pylab.show() # show figure on screen

Categories

Resources