0

I am doing some analysis on images (original image format is geotiff - .tif and did some calculations on the images and able to output the calculated pixels into csv without issue. However due to matplotlib limitations of using only inches for figure width and height, i am not able to output the new calculated image into a plot. Original map size is about 7.7k pixels by 7.7k pixels and the output image is of 3.3k by 3.3k without color bar. Below is the code i used to generate the plots

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt    
figure_width_inches = 40
figure_height_inches = 20

img_min = np.nanmin(img)
img_max = np.nanmax(img)
mid = 0

img_fig = plt.figure(figsize=(figure_width_inches, figure_height_inches))
img_ax = img_fig.add_subplot(add_subplot_RPC)

cmap = plt.cm.RdYlGn

img_cax = plt.imshow(img, cmap=cmap, clim=(img_min, img_max))

plt.axis(axis_mode)

img_fig.savefig(img_filename.replace('.jpg', '_notitlenolegend.jpg'), dpi=figure_dpi,
            bbox_inches=figure_bbox_inches, pad_inches=plot_pad_inches)

ax.set_title(img_title, fontsize=axis_title_fontsize, fontweight=axis_title_fontweight)
cbar = img_fig.colorbar(cax, orientation=figure_colourbar_orientation, shrink=figure_colourbar_shrink)
img_fig.savefig(img_filename, dpi=figure_dpi, bbox_inches=figure_bbox_inches, pad_inches=plot_pad_inches)

I need the image output to be of similar size as original image (i.e. 7.7k by 7.7k pixels) for post plot processing. My challenge is that my source file is of geotiff and plt.imread is unable to open the file. I am thinking of converting the tif file to jpg to get plt.imread to open the file but i could not convert it.

source = '~/some_map.tif'

import PIL
import PIL.Image, PIL.ImageFile

img = PIL.Image.open(source)
destination = source.replace('.tif', '_destination.tif')

img.save(destination, "JPEG", quality=10, optimize=True, progressive=True)


...    
IOError: cannot write mode I as JPEG

i might need to convert the color space of the single band geotiff file for pillow to save the file as jpg. But it seems like a tedious approach to the problem.

- Is there a more pythonic way to resolve the image output size of matplotlib

Edit:

figure_dpi = 100
figure_output_dpi = 1000
img_fig = plt.figure(figsize=(width/float(figure_output_dpi), \
                     height/float(figure_output_dpi)), dpi=figure_dpi)
ax = plt.Axes(img_fig, [0., 0., 1., 1.])
ax.set_axis_off()
img_fig.add_axes(ax)

i managed to generate the results i want with this i.e. figure is pixel by pixel identical to the image source.

css
  • 1
  • 1
  • In the first code there is `img`. If you have problems loading your image, what exactly is `img` then? – ImportanceOfBeingErnest Aug 01 '18 at 10:03
  • In your first code what is your `figure_dpi` set to? You should be able to essentially set the number of pixels through the combination of size in inches and dpi. This seems like a duplicate of similar questions: https://stackoverflow.com/questions/13714454/specifying-and-saving-a-figure-with-exact-size-in-pixels – MattB Aug 01 '18 at 11:39
  • @ImportanceOfBeingErnest img is a geotiff file (.tif) and matplotlib isn't able to handle tif files – css Aug 02 '18 at 03:04
  • @MattB my figure_dpi is set to 200. I don't exactly understand how the dpi works in this case since it is screen dependent and i am not trying to use `imshow` to display the image on screen. Based on the link it seems like saving the image in a high dpi is the solution? – css Aug 02 '18 at 03:22
  • So the first code is not working? Or is it? But if it's not working, what is "the output image"? since you can't get any output from a non-working code. Is there a geotiff file you can link to for testing (I don't have any such file available.) – ImportanceOfBeingErnest Aug 02 '18 at 08:07
  • @ImportanceOfBeingErnest first code is partially working in the sense that it is able to generate plots. But currently I am looking for ways to make matplotlib to output images of the same size (pixels width by pixels height) – css Aug 02 '18 at 08:13
  • @MattB from the link, by using `plt.figure(figsize=(3.841, 7.195), dpi=100) ( your code ...) plt.savefig('myfig.png', dpi=1000)` I manage to make it work (i.e output image of same pixel size as source image. But I don't really understand the explanation nor how dpi really works in this case – css Aug 02 '18 at 08:14
  • So the question is not about geotiff. But I still have problems understanding the desired outcome. Do you want the figure to be 7700 pixels wide or the image (axes) inside the figure? Can you refer to [this picture](https://i.stack.imgur.com/dbH7K.png) and clarify what you're looking for? – ImportanceOfBeingErnest Aug 02 '18 at 11:26
  • @ImportanceOfBeingErnest i am generating 2 images based on the geotiff. 1 with axes and 1 without. The one without axes will be of 7.7k by 7.7k pixels, pixel by pixel equivalent to the image source. in my code i named it _notitlenolegend_ . Based on the picture u referenced, the image source would be everything you see in the axes, plotting it in the figure without aes. After added axes in, i don't need it to be pixel by pixel equivalent, so i can just plot it in the figure with size 7.7k by 7.7k. Anyway i managed to generate what I want just that i don't understand why. – css Aug 03 '18 at 01:55

0 Answers0