Exporting plot with given scale and DPI

8 messages
Open this post in threaded view
|

Exporting plot with given scale and DPI

 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
Open this post in threaded view
|

Re: Exporting plot with given scale and DPI

 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
Open this post in threaded view
|

Re: Exporting plot with given scale and DPI

 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
Open this post in threaded view
|

Re: Exporting plot with given scale and DPI

 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
Open this post in threaded view
|

Re: Exporting plot with given scale and DPI

 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/dx03E6And here is correct result I get with fig.show() added before savefig() https://ibb.co/gZ0ygmAny 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
Open this post in threaded view
|

Re: Exporting plot with given scale and DPI

 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