Ответ 1
Просто для правильного ответа DSM. По умолчанию графики имеют больше пикселей вдоль одной оси над другой. Когда вы добавляете круг, он традиционно добавляется в единицы данных. Если ваши оси имеют симметричный диапазон, это означает, что один шаг вдоль оси x будет включать в себя другое количество пикселей, чем один шаг вдоль вашей оси y. Таким образом, симметричный круг в единицах данных является асимметричным в единицах пикселя (что вы на самом деле видите).
Как правильно указал DSM, вы можете заставить оси x и y иметь равное количество пикселей на единицу данных. Это делается с использованием методов plt.axis("equal")
или ax.axis("equal")
(где ax
является экземпляром Axes
).
Вы также можете нарисовать Ellipse
так, чтобы он был соответствующим образом масштабирован, чтобы выглядеть как круг на вашем сюжете. Вот пример такого случая:
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse, Circle
fig = plt.figure()
ax1 = fig.add_subplot(211)
# calculate asymmetry of x and y axes:
x0, y0 = ax1.transAxes.transform((0, 0)) # lower left in pixels
x1, y1 = ax1.transAxes.transform((1, 1)) # upper right in pixes
dx = x1 - x0
dy = y1 - y0
maxd = max(dx, dy)
width = .15 * maxd / dx
height = .15 * maxd / dy
# a circle you expect to be a circle, but it is not
ax1.add_artist(Circle((.5, .5), .15))
# an ellipse you expect to be an ellipse, but it a circle
ax1.add_artist(Ellipse((.75, .75), width, height))
ax2 = fig.add_subplot(212)
ax2.axis('equal')
# a circle you expect to be a circle, and it is
ax2.add_artist(Circle((.5, .5), .15))
# an ellipse you expect to be an ellipse, and it is
ax2.add_artist(Ellipse((.75, .75), width, height))
fig.savefig('perfectCircle1.png')
что приводит к этой цифре:
В качестве альтернативы вы можете настроить фигуру так, чтобы Axes
были квадратными:
# calculate dimensions of axes 1 in figure units
x0, y0, dx, dy = ax1.get_position().bounds
maxd = max(dx, dy)
width = 6 * maxd / dx
height = 6 * maxd / dy
fig.set_size_inches((width, height))
fig.savefig('perfectCircle2.png')
в результате:
Обратите внимание, что теперь у вторых осей, имеющих опцию axis("equal")
, тот же диапазон для осей x и y. Эта цифра была масштабирована так, чтобы единицы даты каждого были представлены одинаковым количеством пикселей.
Вы также можете настроить оси на квадратные, даже если фигура отсутствует. Или вы можете изменить преобразование по умолчанию для круга в None
, что означает, что используемые единицы являются пикселями. У меня с трудом удается это сделать в данный момент (круг - это круг, но не там, где я хочу, чтобы он был).