Exporting plot with given scale and DPI

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Exporting plot with given scale and DPI

Alexander Bruy
Hi all.

I use matplotlib inside PyQt app and want to export plot into PNG image with
some user-defined scale and DPI. So after printing that image I should be able
to measure on the paper according to the scale.

For example, length of the profile line is 500m (this is my x-axis),
scale set to 1:10000 and DPI is 150. 500m at 1:10000 should result in
a 5cm print out. Taking 150 DPI into account resulting bitmap should
be 295 pixels wide:

 1cm is 0.393701 inches
 5cm is 1.968505 inches
 1.968505inches * 150DPI = 295.27575 px

Also it is necessary to take into account that resulting image may be
really big, for
example if profile line length is several kilometers and DPI is 600.

As I can see there is a 'dpi' parameter in the savefig() call, but I
can't figure out how
to adjust size of the existing figure when exporting. Can you help me?

Thanks
--
Alexander Bruy
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Exporting plot with given scale and DPI

Jody Klymak
Does `fig.set_size_inches()` do what you want?

Cheers,   Jody

> On 8 Jan 2018, at 08:44, Alexander Bruy <[hidden email]> wrote:
>
> Hi all.
>
> I use matplotlib inside PyQt app and want to export plot into PNG image with
> some user-defined scale and DPI. So after printing that image I should be able
> to measure on the paper according to the scale.
>
> For example, length of the profile line is 500m (this is my x-axis),
> scale set to 1:10000 and DPI is 150. 500m at 1:10000 should result in
> a 5cm print out. Taking 150 DPI into account resulting bitmap should
> be 295 pixels wide:
>
> 1cm is 0.393701 inches
> 5cm is 1.968505 inches
> 1.968505inches * 150DPI = 295.27575 px
>
> Also it is necessary to take into account that resulting image may be
> really big, for
> example if profile line length is several kilometers and DPI is 600.
>
> As I can see there is a 'dpi' parameter in the savefig() call, but I
> can't figure out how
> to adjust size of the existing figure when exporting. Can you help me?
>
> Thanks
> --
> Alexander Bruy
> _______________________________________________
> Matplotlib-users mailing list
> [hidden email]
> https://mail.python.org/mailman/listinfo/matplotlib-users

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





_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Exporting plot with given scale and DPI

Alexander Bruy
It is not clear from the docs if this function preserves dimensions and DPI
when exporting plot into PNG.

Also as I understand it resizes plot on screen and does not play well with
large sizes.

2018-01-08 19:20 GMT+02:00 Jody Klymak <[hidden email]>:

> Does `fig.set_size_inches()` do what you want?
>
> Cheers,   Jody
>
>> On 8 Jan 2018, at 08:44, Alexander Bruy <[hidden email]> wrote:
>>
>> Hi all.
>>
>> I use matplotlib inside PyQt app and want to export plot into PNG image with
>> some user-defined scale and DPI. So after printing that image I should be able
>> to measure on the paper according to the scale.
>>
>> For example, length of the profile line is 500m (this is my x-axis),
>> scale set to 1:10000 and DPI is 150. 500m at 1:10000 should result in
>> a 5cm print out. Taking 150 DPI into account resulting bitmap should
>> be 295 pixels wide:
>>
>> 1cm is 0.393701 inches
>> 5cm is 1.968505 inches
>> 1.968505inches * 150DPI = 295.27575 px
>>
>> Also it is necessary to take into account that resulting image may be
>> really big, for
>> example if profile line length is several kilometers and DPI is 600.
>>
>> As I can see there is a 'dpi' parameter in the savefig() call, but I
>> can't figure out how
>> to adjust size of the existing figure when exporting. Can you help me?
>>
>> Thanks
>> --
>> Alexander Bruy
>> _______________________________________________
>> Matplotlib-users mailing list
>> [hidden email]
>> https://mail.python.org/mailman/listinfo/matplotlib-users
>
> --
> Jody Klymak
> http://web.uvic.ca/~jklymak/
>
>
>
>
>



--
Alexander Bruy
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Exporting plot with given scale and DPI

Eric Firing
You are correct that if you are displaying a plot on the screen, the
figure size will be changed to fit.  This is a shortcoming of all the
mpl backends; the plot windows should have automatic scrollbars instead.
The workaround is simple, though: When you make the figure, use a small
enough dpi so that the window will fit on the screen.  Then use your
desired dpi when you save:

fig, ax = plt.subplots(figsize=(20,30), dpi=20)
# ... plot something...
fig.savefig('bigplot.png', dpi=150)

Assuming you have a typical screen size, the above will result in the
following output from the "file" command (in Linux or OSX):

bigplot.png: PNG image data, 3000 x 4500, 8-bit/color RGBA, non-interlaced

As you see, it is consistent with the requested figsize and file dpi.

Eric

On 2018/01/08 7:45 AM, Alexander Bruy wrote:

> It is not clear from the docs if this function preserves dimensions and DPI
> when exporting plot into PNG.
>
> Also as I understand it resizes plot on screen and does not play well with
> large sizes.
>
> 2018-01-08 19:20 GMT+02:00 Jody Klymak <[hidden email]>:
>> Does `fig.set_size_inches()` do what you want?
>>
>> Cheers,   Jody
>>
>>> On 8 Jan 2018, at 08:44, Alexander Bruy <[hidden email]> wrote:
>>>
>>> Hi all.
>>>
>>> I use matplotlib inside PyQt app and want to export plot into PNG image with
>>> some user-defined scale and DPI. So after printing that image I should be able
>>> to measure on the paper according to the scale.
>>>
>>> For example, length of the profile line is 500m (this is my x-axis),
>>> scale set to 1:10000 and DPI is 150. 500m at 1:10000 should result in
>>> a 5cm print out. Taking 150 DPI into account resulting bitmap should
>>> be 295 pixels wide:
>>>
>>> 1cm is 0.393701 inches
>>> 5cm is 1.968505 inches
>>> 1.968505inches * 150DPI = 295.27575 px
>>>
>>> Also it is necessary to take into account that resulting image may be
>>> really big, for
>>> example if profile line length is several kilometers and DPI is 600.
>>>
>>> As I can see there is a 'dpi' parameter in the savefig() call, but I
>>> can't figure out how
>>> to adjust size of the existing figure when exporting. Can you help me?
>>>
>>> Thanks
>>> --
>>> Alexander Bruy
>>> _______________________________________________
>>> Matplotlib-users mailing list
>>> [hidden email]
>>> https://mail.python.org/mailman/listinfo/matplotlib-users
>>
>> --
>> Jody Klymak
>> http://web.uvic.ca/~jklymak/
>>
>>
>>
>>
>>
>
>
>

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Exporting plot with given scale and DPI

Alexander Bruy
Hi,

thanks for the hints, I have adopted your suggestions but still have
some issues.
Now my workflow looks like this:
1. get scale and DPI from user
2. calculate figure width and height in inches based on scale and DPI
3. make a figure with calculated width and height and small DPI value
    fig = plt.figure(figsize=(imgWidth, imgWidth), dpi=10)
4. plot profile line
5. export figure with correct DPI
    fig.savefig(fileName, dpi=int(userDPI), format="png", bbox_inches="tight")

Unfortunately, when I export figure with correct DPI I get incorrect image
dimensions. After some experiments, I have found that adding fig.show()
*before* the savefig() call fixes things and resulting image is correct.

Here is the image obtained without fig.show()
for example https://ibb.co/dx03E6

And here is correct result I get with fig.show() added before savefig()
https://ibb.co/gZ0ygm

Any ideas what can be wrong? I tried to remove bbox_inches="tight" but
still no luck, output is not correct anyway. Using mpl.use('Agg') or similar
things is not possible as matplotlib embeeded into Qt application.

I can live with fig.show() workaround, but need a way to close plot window
programmaticaly after saving the figure.

2018-01-08 21:29 GMT+02:00 Eric Firing <[hidden email]>:

> You are correct that if you are displaying a plot on the screen, the figure
> size will be changed to fit.  This is a shortcoming of all the mpl backends;
> the plot windows should have automatic scrollbars instead. The workaround is
> simple, though: When you make the figure, use a small enough dpi so that the
> window will fit on the screen.  Then use your desired dpi when you save:
>
> fig, ax = plt.subplots(figsize=(20,30), dpi=20)
> # ... plot something...
> fig.savefig('bigplot.png', dpi=150)
>
> Assuming you have a typical screen size, the above will result in the
> following output from the "file" command (in Linux or OSX):
>
> bigplot.png: PNG image data, 3000 x 4500, 8-bit/color RGBA, non-interlaced
>
> As you see, it is consistent with the requested figsize and file dpi.
>
> Eric
>
>
> On 2018/01/08 7:45 AM, Alexander Bruy wrote:
>>
>> It is not clear from the docs if this function preserves dimensions and
>> DPI
>> when exporting plot into PNG.
>>
>> Also as I understand it resizes plot on screen and does not play well with
>> large sizes.
>>
>> 2018-01-08 19:20 GMT+02:00 Jody Klymak <[hidden email]>:
>>>
>>> Does `fig.set_size_inches()` do what you want?
>>>
>>> Cheers,   Jody
>>>
>>>> On 8 Jan 2018, at 08:44, Alexander Bruy <[hidden email]>
>>>> wrote:
>>>>
>>>> Hi all.
>>>>
>>>> I use matplotlib inside PyQt app and want to export plot into PNG image
>>>> with
>>>> some user-defined scale and DPI. So after printing that image I should
>>>> be able
>>>> to measure on the paper according to the scale.
>>>>
>>>> For example, length of the profile line is 500m (this is my x-axis),
>>>> scale set to 1:10000 and DPI is 150. 500m at 1:10000 should result in
>>>> a 5cm print out. Taking 150 DPI into account resulting bitmap should
>>>> be 295 pixels wide:
>>>>
>>>> 1cm is 0.393701 inches
>>>> 5cm is 1.968505 inches
>>>> 1.968505inches * 150DPI = 295.27575 px
>>>>
>>>> Also it is necessary to take into account that resulting image may be
>>>> really big, for
>>>> example if profile line length is several kilometers and DPI is 600.
>>>>
>>>> As I can see there is a 'dpi' parameter in the savefig() call, but I
>>>> can't figure out how
>>>> to adjust size of the existing figure when exporting. Can you help me?
>>>>
>>>> Thanks
>>>> --
>>>> Alexander Bruy
>>>> _______________________________________________
>>>> Matplotlib-users mailing list
>>>> [hidden email]
>>>> https://mail.python.org/mailman/listinfo/matplotlib-users
>>>
>>>
>>> --
>>> Jody Klymak
>>> http://web.uvic.ca/~jklymak/
>>>
>>>
>>>
>>>
>>>
>>
>>
>>
>
> _______________________________________________
> Matplotlib-users mailing list
> [hidden email]
> https://mail.python.org/mailman/listinfo/matplotlib-users



--
Alexander Bruy
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Exporting plot with given scale and DPI

Eric Firing
It looks like somewhere you are setting an aspect ratio of 1 (or
'equal') and the difference between the examples is that the first is
with adjustable 'box' and the second is with adjustable 'datalim'.

Are you doing any sharing or twinning of axes?

In place of the call to show, try putting in

ax.set_aspect('datalim')
ax.apply_aspect()

Eric

On 2018/01/09 6:58 AM, Alexander Bruy wrote:

> Hi,
>
> thanks for the hints, I have adopted your suggestions but still have
> some issues.
> Now my workflow looks like this:
> 1. get scale and DPI from user
> 2. calculate figure width and height in inches based on scale and DPI
> 3. make a figure with calculated width and height and small DPI value
>      fig = plt.figure(figsize=(imgWidth, imgWidth), dpi=10)
> 4. plot profile line
> 5. export figure with correct DPI
>      fig.savefig(fileName, dpi=int(userDPI), format="png", bbox_inches="tight")
>
> Unfortunately, when I export figure with correct DPI I get incorrect image
> dimensions. After some experiments, I have found that adding fig.show()
> *before* the savefig() call fixes things and resulting image is correct.
>
> Here is the image obtained without fig.show()
> for example https://ibb.co/dx03E6
>
> And here is correct result I get with fig.show() added before savefig()
> https://ibb.co/gZ0ygm
>
> Any ideas what can be wrong? I tried to remove bbox_inches="tight" but
> still no luck, output is not correct anyway. Using mpl.use('Agg') or similar
> things is not possible as matplotlib embeeded into Qt application.
>
> I can live with fig.show() workaround, but need a way to close plot window
> programmaticaly after saving the figure.
>
> 2018-01-08 21:29 GMT+02:00 Eric Firing <[hidden email]>:
>> You are correct that if you are displaying a plot on the screen, the figure
>> size will be changed to fit.  This is a shortcoming of all the mpl backends;
>> the plot windows should have automatic scrollbars instead. The workaround is
>> simple, though: When you make the figure, use a small enough dpi so that the
>> window will fit on the screen.  Then use your desired dpi when you save:
>>
>> fig, ax = plt.subplots(figsize=(20,30), dpi=20)
>> # ... plot something...
>> fig.savefig('bigplot.png', dpi=150)
>>
>> Assuming you have a typical screen size, the above will result in the
>> following output from the "file" command (in Linux or OSX):
>>
>> bigplot.png: PNG image data, 3000 x 4500, 8-bit/color RGBA, non-interlaced
>>
>> As you see, it is consistent with the requested figsize and file dpi.
>>
>> Eric
>>
>>
>> On 2018/01/08 7:45 AM, Alexander Bruy wrote:
>>>
>>> It is not clear from the docs if this function preserves dimensions and
>>> DPI
>>> when exporting plot into PNG.
>>>
>>> Also as I understand it resizes plot on screen and does not play well with
>>> large sizes.
>>>
>>> 2018-01-08 19:20 GMT+02:00 Jody Klymak <[hidden email]>:
>>>>
>>>> Does `fig.set_size_inches()` do what you want?
>>>>
>>>> Cheers,   Jody
>>>>
>>>>> On 8 Jan 2018, at 08:44, Alexander Bruy <[hidden email]>
>>>>> wrote:
>>>>>
>>>>> Hi all.
>>>>>
>>>>> I use matplotlib inside PyQt app and want to export plot into PNG image
>>>>> with
>>>>> some user-defined scale and DPI. So after printing that image I should
>>>>> be able
>>>>> to measure on the paper according to the scale.
>>>>>
>>>>> For example, length of the profile line is 500m (this is my x-axis),
>>>>> scale set to 1:10000 and DPI is 150. 500m at 1:10000 should result in
>>>>> a 5cm print out. Taking 150 DPI into account resulting bitmap should
>>>>> be 295 pixels wide:
>>>>>
>>>>> 1cm is 0.393701 inches
>>>>> 5cm is 1.968505 inches
>>>>> 1.968505inches * 150DPI = 295.27575 px
>>>>>
>>>>> Also it is necessary to take into account that resulting image may be
>>>>> really big, for
>>>>> example if profile line length is several kilometers and DPI is 600.
>>>>>
>>>>> As I can see there is a 'dpi' parameter in the savefig() call, but I
>>>>> can't figure out how
>>>>> to adjust size of the existing figure when exporting. Can you help me?
>>>>>
>>>>> Thanks
>>>>> --
>>>>> Alexander Bruy
>>>>> _______________________________________________
>>>>> Matplotlib-users mailing list
>>>>> [hidden email]
>>>>> https://mail.python.org/mailman/listinfo/matplotlib-users
>>>>
>>>>
>>>> --
>>>> Jody Klymak
>>>> http://web.uvic.ca/~jklymak/
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>
>> _______________________________________________
>> Matplotlib-users mailing list
>> [hidden email]
>> https://mail.python.org/mailman/listinfo/matplotlib-users
>
>
>

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Exporting plot with given scale and DPI

Alexander Bruy
Hi Eric,

2018-01-10 18:46 GMT+02:00 Eric Firing <[hidden email]>:
> It looks like somewhere you are setting an aspect ratio of 1 (or 'equal')
> and the difference between the examples is that the first is with adjustable
> 'box' and the second is with adjustable 'datalim'.

Right, I create axes using following code:

axes = fig.add_axes((LEFT_MARGIN, BOTTOM_MARGIN, RIGHT_MARGIN, TOP_MARGIN),
                                  adjustable="datalim",  aspect=1)

> Are you doing any sharing or twinning of axes?

No sharing or twinning, just single line and one pair (X and Y) of axes.

--
Alexander Bruy
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Exporting plot with given scale and DPI

Jody Klymak
Can you give us a minimal self-contained working example of exactly what you are trying to do?  

Cheers,   Jody




> On 10 Jan 2018, at 09:58, Alexander Bruy <[hidden email]> wrote:
>
> Hi Eric,
>
> 2018-01-10 18:46 GMT+02:00 Eric Firing <[hidden email]>:
>> It looks like somewhere you are setting an aspect ratio of 1 (or 'equal')
>> and the difference between the examples is that the first is with adjustable
>> 'box' and the second is with adjustable 'datalim'.
>
> Right, I create axes using following code:
>
> axes = fig.add_axes((LEFT_MARGIN, BOTTOM_MARGIN, RIGHT_MARGIN, TOP_MARGIN),
>                                  adjustable="datalim",  aspect=1)
>
>> Are you doing any sharing or twinning of axes?
>
> No sharing or twinning, just single line and one pair (X and Y) of axes.
>
> --
> Alexander Bruy
> _______________________________________________
> Matplotlib-users mailing list
> [hidden email]
> https://mail.python.org/mailman/listinfo/matplotlib-users

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





_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users