Home > Software engineering >  Avoid distortring squares/circles in Matplotlib figure with fixed figsize
Avoid distortring squares/circles in Matplotlib figure with fixed figsize

Time:01-06

In a Matplotlib figure with aspect ratio 12:5, a square is drawn on ax and 4 circles on ax2. The 4 circles are then redrawn with different colors.

However, the square looks like a rectangle, and the circles look like ellipses.

enter image description here Is it possible to maintain the figure aspect ratio without distorting the square and circles?

import matplotlib.pyplot as plt

def draw():
    
    ax.set_xlim(-1, 7)
    ax.set_ylim(-1, 7)
    
    ax2.set_xlim(-1, 7)
    ax2.set_ylim(-1, 7)
    ax2.set_xticks([])
    ax2.set_yticks([])

    p = plt.Rectangle((0,0), 5, 5)
    ax.add_patch(p)

    ax2.add_patch(plt.Circle((0,0), 0.1, color="r"))
    ax2.add_patch(plt.Circle((0,5), 0.1, color="r"))
    ax2.add_patch(plt.Circle((5,0), 0.1, color="r"))
    ax2.add_patch(plt.Circle((5,5), 0.1, color="r"))
    
def redraw():
    ax2.clear()

    ax2.set_xticks([])
    ax2.set_yticks([])
    ax2.set_xlim(-1, 7)
    ax2.set_ylim(-1, 7)

    ax2.add_patch(plt.Circle((0,0), 0.1, color="g"))
    ax2.add_patch(plt.Circle((0,5), 0.1, color="r"))
    ax2.add_patch(plt.Circle((5,0), 0.1, color="g"))
    ax2.add_patch(plt.Circle((5,5), 0.1, color="r"))
    
fig, ax = plt.subplots(figsize=(12, 5)) # needs to be non-square
ax2 = ax.twinx().twiny()
draw()
redraw()

CodePudding user response:

If you want no distortion, you need to change the limits on the x axis. You can change the xlimit according to the aspect ratio 12:5 = 2.4:

import matplotlib.pyplot as plt


def draw():

    ax.set_xlim(-1, 7 * 2.4)
    ax.set_ylim(-1, 7)

    ax2.set_xlim(-1, 7 * 2.4)
    ax2.set_ylim(-1, 7)
    ax2.set_xticks([])
    ax2.set_yticks([])

    p = plt.Rectangle((0, 0), 5, 5)
    ax.add_patch(p)

    ax2.add_patch(plt.Circle((0, 0), 0.1, color="r"))
    ax2.add_patch(plt.Circle((0, 5), 0.1, color="r"))
    ax2.add_patch(plt.Circle((5, 0), 0.1, color="r"))
    ax2.add_patch(plt.Circle((5, 5), 0.1, color="r"))


def redraw():
    ax2.clear()

    ax2.set_xticks([])
    ax2.set_yticks([])
    ax2.set_xlim(-1, 7 * 2.4)
    ax2.set_ylim(-1, 7)

    ax2.add_patch(plt.Circle((0, 0), 0.1, color="g"))
    ax2.add_patch(plt.Circle((0, 5), 0.1, color="r"))
    ax2.add_patch(plt.Circle((5, 0), 0.1, color="g"))
    ax2.add_patch(plt.Circle((5, 5), 0.1, color="r"))


fig, ax = plt.subplots(figsize=(12, 5))  # needs to be non-square
ax2 = ax.twinx().twiny()
draw()
redraw()

This yields the following figure

  • Related