How to obtain a fixed height in pixels, fixed data x/y aspect ratio and automatically remove remove horizontal whitespace margin in Matplotlib?

后端 未结 2 429
情深已故
情深已故 2020-12-21 23:32

Let\'s take this as a starting point based on: Specifying and saving a figure with exact size in pixels

#!/usr/bin/env python3

import sys

import numpy as np         


        
相关标签:
2条回答
  • 2020-12-22 00:01

    I don't know if I understood your question, but if you want to limit the whitespace in a figure with a 1x2 subplot layout, you simply have to create a figure with a width that's half the height:

    h = 400
    nrows = 2
    w = h/nrows
    dpi = 100
    
    fig, ax = plt.subplots(nrows=nrows, ncols=1, figsize=(w/dpi, h/dpi), dpi=dpi)
    
    t = np.arange(-10., 10., 1.)
    a = ax[0]
    a.set_aspect(1)
    a.plot(t, t, '.')
    a = ax[1]
    a.plot(t, -t, '.')
    a.set_aspect(1)
    plt.tight_layout(pad=1)
    plt.savefig(
        'main.png',
        format='png',
        dpi=dpi,
        facecolor='y',
    )
    

    >> identify main.png

    main.png PNG 200x400 200x400+0+0 8-bit sRGB 6048B 0.000u 0:00.000

    0 讨论(0)
  • 2020-12-22 00:17

    SVG output + plt.savefig(bbox_inches='tight' + Inkscape convert

    This is terrible, but it does what I want without a lot of extra boilerplate, so here we go:

    #!/usr/bin/env python3
    
    import sys
    
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib as mpl
    
    h = int(sys.argv[1])
    fig, ax = plt.subplots(nrows=2, ncols=1)
    t = np.arange(-10., 10., 1.)
    a = ax[0]
    a.set_aspect(1)
    a.plot(t, t, '.')
    a = ax[1]
    a.plot(t, -t, '.')
    a.set_aspect(1)
    plt.savefig(
        'main.svg',
        format='svg',
        dpi=h/fig.get_size_inches()[1],
        facecolor='y',
        bbox_inches='tight',
    )
    

    and then:

    inkscape -b FFF -e main.png -h 400 main.svg
    

    output:

    bbox_inches='tight' gives a decent looking image without too much borders, but makes me lose the exact size, so we use the SVG output as a way to work around that.

    This should work well since SVG is a vector format, and therefore should scale to any size seamlessly.

    I use Inkscape for the conversion because Imagemagick requires you to manually calculate the resolution:

    • https://superuser.com/questions/598849/imagemagick-convert-how-to-produce-sharp-resized-png-files-from-svg-files/1602059#1602059
    • How to convert a SVG to a PNG with ImageMagick?

    Tested on Inkscape 0.92.5.

    0 讨论(0)
提交回复
热议问题