Using matplotlib, how can I print something “actual size”?

后端 未结 3 1102
孤城傲影
孤城傲影 2021-01-03 02:09

I have a number of plots where the x- and y-axes are in centimeter units, and I am already using axis(\'equal\') to ensure proper aspect ratios. I would like to print out th

相关标签:
3条回答
  • 2021-01-03 02:09

    Another method using fig.add_axes was quite accurate. I have included 1 cm grid as well.

    import matplotlib.pyplot as plt
    import matplotlib as mpl
    
    # This example fits a4 paper with 5mm margin printers
    
    # figure settings
    figure_width = 28.7 # cm
    figure_height = 20 # cm
    left_right_margin = 1 # cm
    top_bottom_margin = 1 # cm
    
    # Don't change
    left   = left_right_margin / figure_width # Percentage from height
    bottom = top_bottom_margin / figure_height # Percentage from height
    width  = 1 - left*2
    height = 1 - bottom*2
    cm2inch = 1/2.54 # inch per cm
    
    # specifying the width and the height of the box in inches
    fig = plt.figure(figsize=(figure_width*cm2inch,figure_height*cm2inch))
    ax = fig.add_axes((left, bottom, width, height))
    
    # limits settings (important)
    plt.xlim(0, figure_width * width)
    plt.ylim(0, figure_height * height)
    
    # Ticks settings
    ax.xaxis.set_major_locator(mpl.ticker.MultipleLocator(5))
    ax.xaxis.set_minor_locator(mpl.ticker.MultipleLocator(1))
    ax.yaxis.set_major_locator(mpl.ticker.MultipleLocator(5))
    ax.yaxis.set_minor_locator(mpl.ticker.MultipleLocator(1))
    
    # Grid settings
    ax.grid(color="gray", which="both", linestyle=':', linewidth=0.5)
    
    # your Plot (consider above limits)
    ax.plot([1,2,3,5,6,7,8,9,10,12,13,14,15,17])
    
    # save figure ( printing png file had better resolution, pdf was lighter and better on screen)
    plt.show()
    fig.savefig('A4_grid_cm.png', dpi=1000)
    fig.savefig('tA4_grid_cm.pdf')
    

    Results:

    0 讨论(0)
  • 2021-01-03 02:17

    Add this to @pablo reyes' answer, check that the printer is at 100%, and it's pretty close;

    ax.set_ylim(0,7)
    ax.set_xlim(0,10)
    
    ax.plot([0.5, 1.5],[0.25, 0.25],label='One cm?')
    ax.plot([6,6],[1,2], label='One cm?')
    ax.legend()
    

    we force the axis to be a size we know, we make its data-transform match the real world, and we can "print a ruler".

    0 讨论(0)
  • 2021-01-03 02:21

    Consider this example. Where I specify exactly the dimension of my axes in cm. matplotlib works in inches, so I convert to inches. And then I also save it with a particular dpi (128) so that it matches the designed dimensions in my display. This of course varies for every display. I found that by trial and error, even though there might be other methods. Well here the code:

    left_margin = 1.   # cm
    right_margin = 1.  # cm
    figure_width = 10. # cm
    figure_height = 7. # cm
    top_margin = 1.    # cm
    bottom_margin = 1. # cm
    
    box_width = left_margin + figure_width + right_margin   # cm
    box_height = top_margin + figure_height + bottom_margin # cm
    
    cm2inch = 1/2.54 # inch per cm
    
    # specifying the width and the height of the box in inches
    fig = figure(figsize=(box_width*cm2inch,box_height*cm2inch))
    ax = fig.add_subplot(111)
    ax.plot([1,2,3])
    
    fig.subplots_adjust(left   = left_margin / box_width,
                        bottom = bottom_margin / box_height,
                        right  = 1. - right_margin / box_width,
                        top    = 1. - top_margin   / box_height,
                        )
    fig.savefig('ten_x_seven_cm.png', dpi=128)
    # dpi = 128 is what works in my display for matching the designed dimensions.
    
    0 讨论(0)
提交回复
热议问题