Why is canvas.print_figure to a png reduce the real size of my image

Hi! I spent a good part of yesterday trying to figure this out on my own,
without success, so I'm posting. I have a 3601x2401 pixel, 300 DPI figure
I export to a png using print_figure; here's sample code:

PLB.imshow(rslt) # rslt is a 3601x2401 int-valued array
curfig = PLB.Figure
fig = PLB.gcf()
# next three lines are in my code; don't seem relevant, but I include
them in case they are

ax = fig.gca()
ax.xaxis.set_ticks([])
ax.yaxis.set_ticks([])

fig.canvas.print_figure(fn + '.png',
                        dpi=300,

                        bbox_inches='tight',

                        pad_inches=-1.0 / 72)

The resulting png is neither the right number of pixels by pixels, nor
the right number of inches by incheses; what's more the resulting png
differs depending on whether I use imshow or matshow (which I also
tried).

What's going on, and how do I "fix" it? (If I really am getting the
full resolution figure, despite what the png is telling me are the
pixel counts, why are the physical dimensions off, and why is the png
telling me that the pixel counts are different? If it has something
to do with compression, is there some undocumented way to say "no
compression" and will that have the desired effect?)

Thanks!

DLG
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20171020/9da0967d/attachment.html>

Hi David,

What are you trying to achieve as the output? An image with no white space?

`bbox_inches=tight` changes the size of the figure to get rid of white space around it. Prob not what you really want.

Drilling down into `canvas` shouldn?t really be necessary.

What is `PLB`? etc?

This will get you pretty close if you just want an image w/ no white space. But I?m not 100% sure that every pixel has been preserved?

import matplotlib.pyplot as plt
import numpy as np

im = np.floor(np.random.rand(3601,2401)*100)

fig, ax = plt.subplots(figsize = (2401/300, 3601/300), dpi=300)

# turn off axis and labels
ax.set_axis_off()
# fill the figure
ax.set_position([0., 0., 1., 1.])
ax.imshow(im)
fig.savefig('Test.png', dpi=300)
···

On 20 Oct 2017, at 14:38 PM, David Goldsmith <eulergaussriemann at gmail.com> wrote:

Hi! I spent a good part of yesterday trying to figure this out on my own, without success, so I'm posting. I have a 3601x2401 pixel, 300 DPI figure I export to a png using print_figure; here's sample code:

PLB.imshow(rslt) # rslt is a 3601x2401 int-valued array
curfig = PLB.Figure
fig = PLB.gcf()
# next three lines are in my code; don't seem relevant, but I include them in case they are
ax = fig.gca()
ax.xaxis.set_ticks()
ax.yaxis.set_ticks()

fig.canvas.print_figure(fn + '.png',
                        dpi=300,
                        bbox_inches='tight',
                        pad_inches=-1.0 / 72)
The resulting png is neither the right number of pixels by pixels, nor the right number of inches by incheses; what's more the resulting png differs depending on whether I use imshow or matshow (which I also tried).
What's going on, and how do I "fix" it? (If I really am getting the full resolution figure, despite what the png is telling me are the pixel counts, why are the physical dimensions off, and why is the png telling me that the pixel counts are different? If it has something to do with compression, is there some undocumented way to say "no compression" and will that have the desired effect?)
Thanks!
DLG

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users at python.org
Matplotlib-users Info Page

--
Jody Klymak

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20171020/998a88fe/attachment.html&gt;

Hi! I spent a good part of yesterday trying to figure this out on my own,
without success, so I'm posting. I have a 3601x2401 pixel, 300 DPI figure
I export to a png using print_figure; here's sample code:

David,

If you are trying to write the numpy array directly to a PNG file, an
alternative to matplotlib is a package that I created called numpngw:
numpngw · PyPI (github:
GitHub - WarrenWeckesser/numpngw: Functions that create PNG and animated PNG files from numpy arrays.). Both those links show several
examples of its use. numpngw uses just Python and NumPy, so it is easy to
install.

Warren

PLB.imshow(rslt) # rslt is a 3601x2401 int-valued array

curfig = PLB.Figure
fig = PLB.gcf()
# next three lines are in my code; don't seem relevant, but I include them in case they are

ax = fig.gca()
ax.xaxis.set_ticks()
ax.yaxis.set_ticks()

fig.canvas.print_figure(fn + '.png',
                        dpi=300,

                        bbox_inches='tight',

                        pad_inches=-1.0 / 72)

The resulting png is neither the right number of pixels by pixels, nor the right number of inches by incheses; what's more the resulting png differs depending on whether I use imshow or matshow (which I also tried).

What's going on, and how do I "fix" it? (If I really am getting the full resolution figure, despite what the png is telling me are the pixel counts, why are the physical dimensions off, and why is the png telling me that the pixel counts are different? If it has something to do with compression, is there some undocumented way to say "no compression" and will that have the desired effect?)

Thanks!

DLG

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users at python.org
Matplotlib-users Info Page

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20171020/bbd1104b/attachment-0001.html&gt;

···

On Fri, Oct 20, 2017 at 5:38 PM, David Goldsmith < eulergaussriemann at gmail.com> wrote:

Hi David,

What are you trying to achieve as the output? An image with no white
space?

Yes, and no edge, but one that replaces that white space with my figure.
in other words, if what is going on is that my figure w/ the white space
is what is 3600x2400, how do I get the full 3600x2400 to be my figure? (I
don?t care if it puts white space around that because I figured out an
?alternative? way to get rid of that). But mostly, I?d just like to
understand what?s going on, because what?s happening now makes absolutely
no sense to me whatsoever.

`bbox_inches=tight` changes the size of the figure to get rid of white
space around it. Prob not what you really want.

OK, so that may be the problem: what?s the ?proper? way to ?get rid of? the
white space, module what I said above.

Drilling down into `canvas` shouldn?t really be necessary.

I?m all ears.

What is `PLB`? etc?

import pylab as PLB

This will get you pretty close if you just want an image w/ no white
space. But I?m not 100% sure that every pixel has been preserved?

import matplotlib.pyplot as plt
import numpy as np

im = np.floor(np.random.rand(3601,2401)*100)

fig, ax = plt.subplots(figsize = (2401/300, 3601/300), dpi=300)

# turn off axis and labels
ax.set_axis_off()
# fill the figure
ax.set_position([0., 0., 1., 1.])
ax.imshow(im)
fig.savefig('Test.png', dpi=300)

Ok, I?ll try that, thanks.

DLG


Hi\!  I spent a good part of yesterday trying to figure this out on my own,
without success, so I&#39;m posting\.  I have a 3601x2401 pixel, 300 DPI figure
I export to a png using print\_figure; here&#39;s sample code:

PLB\.imshow\(rslt\) \# rslt is a 3601x2401 int\-valued array
curfig = PLB\.Figure
fig = PLB\.gcf\(\)
\# next three lines are in my code; don&#39;t seem relevant, but I include them in case they are

ax = fig\.gca\(\)
ax\.xaxis\.set\_ticks\(\[\]\)
ax\.yaxis\.set\_ticks\(\[\]\)

fig\.canvas\.print\_figure\(fn \+ &#39;\.png&#39;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dpi=300,

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bbox\_inches=&#39;tight&#39;,

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pad\_inches=\-1\.0 / 72\)

The resulting png is neither the right number of pixels by pixels, nor the right number of inches by incheses; what&#39;s more the resulting png differs depending on whether I use imshow or matshow \(which I also tried\)\.

What&#39;s going on, and how do I &quot;fix&quot; it?  \(If I really am getting the full resolution figure, despite what the png is telling me are the pixel counts, why are the physical dimensions off, and why is the png telling me that the pixel counts are different?  If it has something to do with compression, is there some  undocumented way to say &quot;no compression&quot; and will that have the desired effect?\)

Thanks\!

DLG

\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
Matplotlib\-users mailing list
Matplotlib\-users at python\.org
https://mail.python.org/mailman/listinfo/matplotlib-users

\-\-
Jody Klymak
http://web.uvic.ca/~jklymak/

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20171020/45877a32/attachment.html&gt;

···

On Fri, Oct 20, 2017 at 3:00 PM Jody Klymak <jklymak at uvic.ca> wrote:

On 20 Oct 2017, at 14:38 PM, David Goldsmith <eulergaussriemann at gmail.com> > wrote:

Thanks. Does it have pylab?s range of built in color maps? Does it even
use colormaps, or do I have to write my own (or ?copy? them from MPL).

DLG

···

On Fri, Oct 20, 2017 at 3:28 PM Warren Weckesser <warren.weckesser at gmail.com> wrote:

On Fri, Oct 20, 2017 at 5:38 PM, David Goldsmith < > eulergaussriemann at gmail.com> wrote:

Hi! I spent a good part of yesterday trying to figure this out on my
own, without success, so I'm posting. I have a 3601x2401 pixel, 300 DPI
figure I export to a png using print_figure; here's sample code:

David,

If you are trying to write the numpy array directly to a PNG file, an
alternative to matplotlib is a package that I created called numpngw:
numpngw · PyPI (github:
GitHub - WarrenWeckesser/numpngw: Functions that create PNG and animated PNG files from numpy arrays.). Both those links show
several examples of its use. numpngw uses just Python and NumPy, so it is
easy to install.

Warren

PLB.imshow(rslt) # rslt is a 3601x2401 int-valued array

curfig = PLB.Figure
fig = PLB.gcf()
# next three lines are in my code; don't seem relevant, but I include them in case they are

ax = fig.gca()
ax.xaxis.set_ticks()
ax.yaxis.set_ticks()

fig.canvas.print_figure(fn + '.png',
                        dpi=300,

                        bbox_inches='tight',

                        pad_inches=-1.0 / 72)

The resulting png is neither the right number of pixels by pixels, nor the right number of inches by incheses; what's more the resulting png differs depending on whether I use imshow or matshow (which I also tried).

What's going on, and how do I "fix" it? (If I really am getting the full resolution figure, despite what the png is telling me are the pixel counts, why are the physical dimensions off, and why is the png telling me that the pixel counts are different? If it has something to do with compression, is there some undocumented way to say "no compression" and will that have the desired effect?)

Thanks!

DLG

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users at python.org
Matplotlib-users Info Page

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20171020/256c5a63/attachment-0001.html&gt;

Ha!

I think you are approaching this from the point of view of an image processing library or something like Photoshop where you want your image to be 6x8 and 300 dpi, and you expect 1800x2400 pixels.

Thats not *really* what matplotlib is for. It really is for presentation of scientific data. So, I have a 500x600 matrix of data, I may use `imshow` to plot it up, but most people don?t care about the dpi of those pixels, so they will just set the dpi to something that shows all the data clearly. Much more important is the ability to have axis labels, annotations, etc.

Its not to say that you can?t be careful and get what you want. I think what I sent you is pretty close. But the library is not trying to conserve pixels.

Anyway, what I sent should be clear enough. I think what you were missing was setting the figure size to the size you wanted before trying to draw on it.

Cheers, Jody

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20171020/a7a6b538/attachment.html&gt;

···

On 20 Oct 2017, at 15:33 PM, David Goldsmith <eulergaussriemann at gmail.com> wrote:

But mostly, I?d just like to understand what?s going on, because what?s happening now makes absolutely no sense to me whatsoever.

OK, thanks for your help.

What I?m doing is somewhere in between: I?m making my own ?fractals,? ?from
scratch?; so if im going to the trouble of computing a 3600x2400 grid so
that I can have a 300 DPI image end up being 12x8, that?s what I want to
end up with (i don?t want to compute any more than I have to, but by the
same token, I want to see everything I?m computing). Anyway, i?ll see if
that does what I?m after and reply again if not. (Though I?d still like to
know what?s going on under the hood, so that I can exploit that if I
choose.)

Thanks again!

DLG

···

On Fri, Oct 20, 2017 at 3:44 PM Jody Klymak <jklymak at uvic.ca> wrote:

On 20 Oct 2017, at 15:33 PM, David Goldsmith <eulergaussriemann at gmail.com> > wrote:

But mostly, I?d just like to understand what?s going on, because what?s
happening now makes absolutely no sense to me whatsoever.

Ha!

I think you are approaching this from the point of view of an image
processing library or something like Photoshop where you want your image to
be 6x8 and 300 dpi, and you expect 1800x2400 pixels.

Thats not *really* what matplotlib is for. It really is for presentation
of scientific data. So, I have a 500x600 matrix of data, I may use
`imshow` to plot it up, but most people don?t care about the dpi of those
pixels, so they will just set the dpi to something that shows all the data
clearly. Much more important is the ability to have axis labels,
annotations, etc.

Its not to say that you can?t be careful and get what you want. I think
what I sent you is pretty close. But the library is not trying to conserve
pixels.

Anyway, what I sent should be clear enough. I think what you were missing
was setting the figure size to the size you wanted before trying to draw on
it.

Cheers, Jody

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20171020/cb8256bd/attachment.html&gt;

Fair enough. Just to be safe, just do dpi=600! It?ll be big, but...

Cheers, Jody

···

On Oct 20, 2017, at 16:02 PM, David Goldsmith <eulergaussriemann at gmail.com> wrote:

OK, thanks for your help.

What I?m doing is somewhere in between: I?m making my own ?fractals,? ?from scratch?; so if im going to the trouble of computing a 3600x2400 grid so that I can have a 300 DPI image end up being 12x8, that?s what I want to end up with (i don?t want to compute any more than I have to, but by the same token, I want to see everything I?m computing). Anyway, i?ll see if that does what I?m after and reply again if not. (Though I?d still like to know what?s going on under the hood, so that I can exploit that if I choose.)

Thanks again!

DLG

On Fri, Oct 20, 2017 at 3:44 PM Jody Klymak <jklymak at uvic.ca <mailto:jklymak at uvic.ca>> wrote:

On 20 Oct 2017, at 15:33 PM, David Goldsmith <eulergaussriemann at gmail.com <mailto:eulergaussriemann at gmail.com>> wrote:

But mostly, I?d just like to understand what?s going on, because what?s happening now makes absolutely no sense to me whatsoever.

Ha!

I think you are approaching this from the point of view of an image processing library or something like Photoshop where you want your image to be 6x8 and 300 dpi, and you expect 1800x2400 pixels.

Thats not *really* what matplotlib is for. It really is for presentation of scientific data. So, I have a 500x600 matrix of data, I may use `imshow` to plot it up, but most people don?t care about the dpi of those pixels, so they will just set the dpi to something that shows all the data clearly. Much more important is the ability to have axis labels, annotations, etc.

Its not to say that you can?t be careful and get what you want. I think what I sent you is pretty close. But the library is not trying to conserve pixels.

Anyway, what I sent should be clear enough. I think what you were missing was setting the figure size to the size you wanted before trying to draw on it.

Cheers, Jody

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20171020/5d8b519a/attachment-0001.html&gt;

Thanks. Does it have pylab?s range of built in color maps? Does it even
use colormaps, or do I have to write my own (or ?copy? them from MPL).

No, numpngw doesn't use colormaps. You'd have to map and scale the image
to an array of integers yourself. You could use matplotlib for the
mapping. For example, if foo is a 2-D array of floats with values between
0 and 1, you could do something like

    mapped_foo = mpl.cm.viridis(foo) # Use matplotlib's 'viridis'
colormap.
    maxint = 2**16
    img = np.floor(maxint*mapped_foo)
    img[img == maxint] = maxint - 1
    numpngw.write_png("foo.png", img.astype(np.uint16))

That would create a 16 bit RGB PNG file.

Warren

DLG

Hi! I spent a good part of yesterday trying to figure this out on my
own, without success, so I'm posting. I have a 3601x2401 pixel, 300 DPI
figure I export to a png using print_figure; here's sample code:

David,

If you are trying to write the numpy array directly to a PNG file, an
alternative to matplotlib is a package that I created called numpngw:
numpngw · PyPI (github: https://github.com/
WarrenWeckesser/numpngw). Both those links show several examples of its
use. numpngw uses just Python and NumPy, so it is easy to install.

Warren

PLB.imshow(rslt) # rslt is a 3601x2401 int-valued array

curfig = PLB.Figure
fig = PLB.gcf()
# next three lines are in my code; don't seem relevant, but I include them in case they are

ax = fig.gca()
ax.xaxis.set_ticks()
ax.yaxis.set_ticks()

fig.canvas.print_figure(fn + '.png',
                        dpi=300,

                        bbox_inches='tight',

                        pad_inches=-1.0 / 72)

The resulting png is neither the right number of pixels by pixels, nor the right number of inches by incheses; what's more the resulting png differs depending on whether I use imshow or matshow (which I also tried).

What's going on, and how do I "fix" it? (If I really am getting the full resolution figure, despite what the png is telling me are the pixel counts, why are the physical dimensions off, and why is the png telling me that the pixel counts are different? If it has something to do with compression, is there some undocumented way to say "no compression" and will that have the desired effect?)

Thanks!

DLG

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users at python.org
Matplotlib-users Info Page

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20171021/a238b024/attachment.html&gt;

···

On Fri, Oct 20, 2017 at 6:36 PM, David Goldsmith < eulergaussriemann at gmail.com> wrote:

On Fri, Oct 20, 2017 at 3:28 PM Warren Weckesser < > warren.weckesser at gmail.com> wrote:

On Fri, Oct 20, 2017 at 5:38 PM, David Goldsmith < >> eulergaussriemann at gmail.com> wrote: