Search code examples
pythonmatplotlibhistogram2d

Matplotlib stretches histogram2d vertically


I'm using this code:

fig = plt.figure(num=2, figsize=(8, 8), dpi=80,
                 facecolor='w', edgecolor='k')
x, y = [xy for xy in zip(*self.pulse_time_distance)]
H, xedges, yedges = np.histogram2d(x, y, bins=(25, 25))
extent = [-50, +50, 0, 10]
plt.imshow(H, extent=extent, interpolation='nearest')
plt.colorbar()

to produce a 2D histogram, however, the plot is stretched vertically and I simply can't figure out how to set its size properly:

Matplotlib stretches 2d histogram vertically


Solution

  • Things are "stretched" because you're using imshow. By default, it assumes that you want to display an image where the aspect ratio of the plot will be 1 (in data coordinates).

    If you want to disable this behavior, and have the pixels stretch to fill up the plot, just specify aspect="auto".

    For example, to reproduce your problem (based on your code snippet):

    import matplotlib.pyplot as plt
    import numpy as np
    
    # Generate some data
    x, y = np.random.random((2, 500))
    x *= 10
    
    # Make a 2D histogram
    H, xedges, yedges = np.histogram2d(x, y, bins=(25, 25))
    
    # Plot the results
    fig, ax = plt.subplots(figsize=(8, 8), dpi=80, facecolor='w', edgecolor='k')
    
    extent = [-50, +50, 0, 10]
    im = ax.imshow(H, extent=extent, interpolation='nearest')
    fig.colorbar(im)
    
    plt.show()
    

    enter image description here

    And we can fix it by just adding aspect="auto" to the imshow call:

    import matplotlib.pyplot as plt
    import numpy as np
    
    # Generate some data
    x, y = np.random.random((2, 500))
    x *= 10
    
    # Make a 2D histogram
    H, xedges, yedges = np.histogram2d(x, y, bins=(25, 25))
    
    # Plot the results
    fig, ax = plt.subplots(figsize=(8, 8), dpi=80, facecolor='w', edgecolor='k')
    
    extent = [-50, +50, 0, 10]
    im = ax.imshow(H, extent=extent, interpolation='nearest', aspect='auto')
    fig.colorbar(im)
    
    plt.show()
    

    enter image description here