I want to save an image plotted with matplotlib. For that, I use the function savefig which has different parameters.
The problem is that when I saved the image, this function add additional white pixel.
In short, I would like to save the image I draw with the original size. In other words, if the data I draw has a dimension of 1000x560, I save the image with those dimensions without additional white parts.
Thus in this way a pixel of the saved image coincides with the pixel that the figure of matplotlib can see.
I'm using python 2.7
Can anyone help please?
Thanks
from matplotlib import pyplot as plt
plt.savefig('foo.png', bbox_inches='tight')
Related
Is there a way to convert the imshow object to an image directly in python 2.7 code? I'm trying to obtain the spectrogram of a wav file and use the image to detect edges in it.
I have the code to get the spectrogram, I have the code to detect edges. Now, I'm manually saving the spectrogram and then detecting edges in the image. Is there a way to do it directly with the imshow object in python ?
Using PIL, you can use:
import PIL
from matplotlib import pyplot as plt
plt.plot(range(5), range(5))
canvas = plt.get_current_fig_manager().canvas
plt.draw()
PIL_image = PIL.Image.frombuffer('RGBA', canvas.get_width_height(), canvas.buffer_rgba())
Tried on jupyter, but how it works may depend on the specific backend, so try it for yourself (for me it also mirrored the image, but that's easy to fix afterward, I think).
Also, you would have to draw only the image without the ticks, see scipy: savefig without frames, axes, only content.
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")
This is my first stack overflow question so please correct me if its not a good one:
I am currently processing a bunch of grayscale images as numpy ndarrays (dtype=uint8) in python 2.7. When I resize the images using resized=misc.imresize(image,.1), the resulting image will sometimes show up with different gray levels when I plot it with pyplot. Here is what my code looks like. I would post an image of the result, but I do not have the reputation points yet:
import cv2
from scipy import misc
from matplotlib import pyplot as plt
image=cv2.imread("gray_image.tif",cv2.CV_LOAD_IMAGE_GRAYSCALE)
resize=misc.imresize(image,.1)
plt.subplot(1,2,1),plt.imshow(image,"gray")
plt.subplot(1,2,2),plt.imshow(resize,"gray")
plt.show()
If I write the image to a file, the gray level appears normal.
If I compare the average gray level using numpy:
np.average(image) and np.average(resized),
the average gray level values are about the same, as one would expect.
If I display the image with cv2.imshow, the gray level appears normal.
Its not only an issue with resizing the image, but the gray level also gets screwy when I add images together (when most of one image is black and shouldn't darken the resulting image), and when I build an image pixel-by-pixel such as in:
import numpy as np
image_copy = np.zeros(image.shape)
for row in range(image.shape[0]):
for col in range(image.shape[1]):
image_copy[row,col]=image[row,col]
plt.imshow(image_copy,"gray") #<-- Will sometimes show up darker than original image
plt.show()
Does anyone have an idea as to what may be going on?
I apologize for the wordiness and lack of clarity in this question.
imshow is automatically scaling the color information to fit the whole available range. After resizing, the color range be smaller, resulting in changes of the apparent color (but not of the actual values, which explains why saved images work well).
You likely want to tell imshow not to scale your colors. This can be done using the vmin and vmax arguments as explained in the documentation. You probably want to use something like plt.imshow(image, "gray", vmin=0, vmax=255) to achieve an invariant appearance.
Is there a way to show the row and column axes when displaying an image with cv2.imshow()? I am using the python bindings for opencv3.0
Not that I am aware of.
However, since you are using Python you are not constrained to use the rudimentary plotting capabilities of OpenCV HighGUI.
Instead, you can use the much more competent matplotlib library (or any of the other available Python plotting libraries).
To plot an image, including a default axis you do
import matplotlib.pyplot as plt
plt.imshow(image, interpolation='none') # Plot the image, turn off interpolation
plt.show() # Show the image window
I'm not sure I fully understand the question due to lack of info.
However you can use OpenCV's draw line function to draw a line from the example points (10,10) to (10,190), and another from (10,190) to (190,190)
On an example image that is 200X200 pixels in size, this will draw a line down the left hand side of the image, and a line along the bottom. You can then plot numbers or whatever you want along this line at increments of X-pixels.
Drawing text/numbers to an image is similar to drawing a line.
Once you have drawn the image, show with the usual image.imshow().
See OpenCV's drawing documentation here:
http://docs.opencv.org/modules/core/doc/drawing_functions.html
And an example to get you going can be found here:
http://opencvexamples.blogspot.com/2013/10/basic-drawing-examples.html#.VMj-bUesXuM
Hope this helps.
I plot a series of figures and save them via savefig as png files (where savefig gets dpi=100 as an argument). The aspect ratio and resolution is previously defined within plt.figure(figsize=(10.24, 10.24), dpi=100), which should result in images of exactly 1024x1024 pixels. I use bbox_inches='tight' as well as plt.tight_layout(), but I still get image dimensions that vary about a few pixels from one image to the next, depending on the axis labels it seems.
Did I miss something? How do I get the exact same image dimensions for every file without losing bbox_inches='tight'? Using matplotlib 1.3.1.