Showing numpy array as image with animation - python

I have a 2D numpy array which I want to show as an image. Now using matplotlib plt.imshow(my_array) works fine. The problem is that my array keeps on changing. There is a function foo() which changes the array. I want to show that array as image and also the changes done by foo function. It should be only one image window and the updates are done in that window instead of creating new one. FuncAnimation is one way but it is used with plots. How can I use it to show image?
My image is actually an arena of obstacles. I am trying to show path finding and visualise it. Breadth-First Search and Dijkstra's algorithm I am trying to visualise.
Kindly help. Thank you.

Not knowing how your code is structured but one solution to your problem could be using plt.pause()
An example,
import numpy as np
from matplotlib import pyplot as plt
def draw_me(img):
plt.pause(.01)
plt.imshow(img)
for idx in range(12):
img = np.random.randint(0, 255, (12,12))
draw_me(img)
note if you are using Sypder make sure you're not inline ploting in the console. For me that means entering the following in the console,
%matplotlib auto
%matplotlib qt

Related

Jupyter and %matplotlib inline lost axis

I am having a really weird issue with using the %matplotlib inline code in my jupyter notebook for plotting graphs using both pyplot and the pandas plotting function.
The problem is they show up without any axes, and basically just show the graph area without anything aside from data points.
I found adding:
import matplotlib as mpl
mpl.rcParams.update(mpl.rcParamsDefault)
reverse it, but I find it odd that should do that every time as the effect disappears as soon as I run %matplotlib inlinecommand.
an example could be
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
plt.scatter(A,A)
plt.tight_layout()
plt.xlabel('here')
plt.show()
This would generate the graph below:
Weird enough if I uses the savefig it get plotted with the axis, if I uses the right-click -> new output -> save as figure, I also get the graph with the figures !!
like this:
Can anyone help me understand what is wrong, which global setting did I mess up, and how do I revert it?
(I don't remember messing around with any settings aside from some settings for pandas, but don't think they should have had an impact)
as mentioned running mpl.rcParams.update(mpl.rcParamsDefault) command does bring it back to normal until I run %matplotlib inline` again !!
Any help would be much appreciated.
Okay I am sorry I think I can answer the question myself now.
With the helpfull #Mr. T asking for the imgur link made me realize what was going on. I had starting using the dark jupyter lab theme, and the graph would generate plots with transparent background, ie. the text and lines where there, but I just couldn't see them.
The trick is to change the background color preferably globally, but that will be a task for tomorrow.

How to draw a Heatmap in a image using the coordinates in Python OpenCV?

I've a huge list of Coordinates(x,y) of people walking in the streets and I like to design a heatmap using those Coordinates(x,y), i.e., it should look something like this. I want much hotter spot for multiple coordinates in a single spot, hotter means red colored spot. I've tried this but ended up getting a heatmap like this not the one I expected nor the site mentioned in the beginning(the wikipedia heatmap). This is the code I tried,
import cv2
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
x,y = [230,150,200],[200,100,150]
plt.imshow(img)
ax = sns.kdeplot(x,y, cmap = "Blues", shade= True, shade_lowest=False)
ax.set_frame_on(False)
plt.axis('off')
plt.savefig('heatmap_pic.png')
This code also made the result image size smaller the actual image was much bigger. I'm new to OpenCV and Matplotlib someone please help me with this, to plot a Heatmap(like this) in a image using a bunch of Coordinates.
You need to take image, create the heatmap, and superimpose it.
Check this or this.

Vector graphics + matplotlib pcolorfast

To keep it short: Is there a way to export plots created with methods like
pcolorfast which basically draw pixels as "real" vector graphics?
I tried to do just that using savefig and saving to a PDF but what would happen is that the plot was actually a vector graphic but the parts drawn by pcolorfast(so basically, what is inside the axes) something like a bitmap. - I checked this using Inkscape.
This resulted in really low resolution plots even though the arrays drawn with pcolorfast where about 3000x4000. I achieved higher resolution by increasing the dpi when exporting, but I'd really appreciate a conversion to a real vector graphic.
Edit: I updated my original code by the piece of code below that should serve to illustrate what exactly I am doing. I tried to involucrate the rasterized tip, but it has had no effect. I still end up with a supersmall PDF-file where the plots are acually raster images (png). I am going to provide you with the data I used and the resulting PDF.
http://www.megafileupload.com/k5ku/test_array1.txt
http://www.megafileupload.com/k5kv/test_array2.txt
http://www.megafileupload.com/k5kw/test.pdf
import numpy as np
import matplotlib.pyplot as plt
arr1= np.loadtxt("test_array1.txt")
arr2= np.loadtxt("test_array2.txt")
fig, (ax1, ax2)=plt.subplots(1, 2)
ax1.set_rasterized(False)
ax1.pcolorfast(arr1)
ax2.pcolorfast(arr2, rasterized=False)
plt.show()
fig.set_rasterized(False)
fig.savefig("test.pdf")

Python how to resize images?

I am getting confused over all the different python datatypes. I wrote a face recognition algorithm in MATLAB, I want to redo it it Python. I am stuck trying to resize my images. How do I do that? Can someone link me to the things that i need to read to understand the difference in the functions between MATLAB in Python? Like MATLAB got imresize but Python got what?
Is there something like import all_matlab_functions so I can python in matlab language ?
I cant believe im struggling so hard. Help! My code below shows how stupid i am with python currently.
%matplotlib inline
import matplotlib.image as mpimg
import glob
import matplotlib.pyplot as plt
image_list = []
for filename in glob.glob('<directory>.pgm'):
im = mpimg.imread(filename)
image_list.append(im) # read all image
from PIL import Image
haha = image_list[1].resize((10 10), resample=0) # try to resize image BUT FAIL
using the jupyter qt-console interpreter, or jupyter notebook you can set the interpreter environment magic %pylab inline so that images will be displayed inline and the matplotlib.pylab namespace and numpy namespaces will be imported into the current namespace. All this means though is that you don't have to prefix the commands with matplotlib.pylab.plot or plt.plot, for example. You can just use plot().
%pylab inline
x = linsapce(1,2*pi,100)
y = sin(x)
plot(x,y)
matplotlib is meant to give good tools for plotting that look similar to matlab plotting, numpy for arrays and mathematics, and scipy gives you tools for more complex functions. For example, scipy.misc.imresize can do what you are looking for:
http://docs.scipy.org/doc/scipy-0.13.0/reference/generated/scipy.misc.imresize.html
If you are looking for a direct way to run your matlab programs outside of matlab, you might want to try Octave instead.
https://www.gnu.org/software/octave/

Python matplotlib imshow is slow

I want to display an image file using imshow. It is an 1600x1200 grayscale image and I found out that matplotlib uses float32 to decode the values. It takes about 2 seconds to load the image and I would like to know if there is any way to make this faster. The point is that I do not really need a high resolution image, I just want to mark certain points and draw the image as a background. So,
First question: Is 2 seconds a good performance for such an image or
can I speed up.
Second question: If it is good performance how can I make the process
faster by reducing the resolution. Important point: I still want the
image to strech over 1600x1200 Pixel in the end.
My code:
import matplotlib
import numpy
plotfig = matplotlib.pyplot.figure()
plotwindow = plotfig.add_subplot(111)
plotwindow.axis([0,1600,0,1200])
plotwindow.invert_yaxis()
img = matplotlib.pyplot.imread("lowres.png")
im = matplotlib.pyplot.imshow(img,cmap=matplotlib.cm.gray,origin='centre')
plotfig.set_figwidth(200.0)
plotfig.canvas.draw()
matplotlib.pyplot.show()
This is what I want to do. Now if the picture saved in lowres.png has a lower resolution as 1600x1200 (i.e. 400x300) it is displayed in the upper corner as it should. How can I scale it to the whole are of 1600x1200 pixel?
If I run this program the slow part comes from the canvas.draw() command below. Is there maybe a way to speed up this command?
Thank you in advance!
According to your suggestions I have updated to the newest version of matplotlib
version 1.1.0svn, checkout 8988
And I also use the following code:
img = matplotlib.pyplot.imread(pngfile)
img *= 255
img2 = img.astype(numpy.uint8)
im = self.plotwindow.imshow(img2,cmap=matplotlib.cm.gray, origin='centre')
and still it takes about 2 seconds to display the image... Any other ideas?
Just to add: I found the following feature
zoomed_inset_axes
So in principle matplotlib should be able to do the task. There one can also plot a picture in a "zoomed" fashion...
The size of the data is independent of the pixel dimensions of the final image.
Since you say you don't need a high-resolution image, you can generate the image quicker by down-sampling your data. If your data is in the form of a numpy array, a quick and dirty way would be to take every nth column and row with data[::n,::n].
You can control the output image's pixel dimensions with fig.set_size_inches and plt.savefig's dpi parameter:
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
data=np.arange(300).reshape((10,30))
plt.imshow(data[::2,::2],cmap=cm.Greys)
fig=plt.gcf()
# Unfortunately, had to find these numbers through trial and error
fig.set_size_inches(5.163,3.75)
ax=plt.gca()
extent=ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
plt.savefig('/tmp/test.png', dpi=400,
bbox_inches=extent)
You can disable the default interpolation of imshow by adding the following line to your matplotlibrc file (typically at ~/.matplotlib/matplotlibrc):
image.interpolation : none
The result is much faster rendering and crisper images.
I found a solution as long as one needs to display only low-resolution images. One can do so using the line
im = matplotlib.pyplot.imshow(img,cmap=matplotlib.cm.gray, origin='centre',extent=(0,1600,0,1200))
where the extent-parameter tells matplotlib to plot the figure over this range. If one uses an image which has a lower resolution, this speeds up the process quite a lot. Nevertheless it would be great if somebody knows additional tricks to make the process even faster in order to use a higher resolution with the same speed.
Thanks to everyone who thought about my problem, further remarks are appreciated!!!

Categories

Resources