当axes
的方面设置为'auto'
时,是否有一种简单可靠的方法来确定ax.get_aspect()
的当前宽高比?
要检查的显而易见的事项是'auto'
,但这只会返回ax.set_aspect(aspect)
。我可以通过ax.get_aspect()
将其设置为任意常量值,之后aspect = 'auto'
返回相同的常量。默认情况下(非常有用)我们有ax.get_data_ratio()
,在这种情况下,自动计算和调整宽高比以匹配数据限制和轴大小。
如何获取自动选择的数字宽高比?
为了澄清,这既不是fig.get_figheight() / fig.get_figwidth()
返回的数据限制的宽高比,也不是图中显示尺寸的宽高比或由def get_aspect(ax=None):
if ax is None:
ax = plt.gca()
fig = ax.figure
ll, ur = ax.get_position() * fig.get_size_inches()
width, height = ur - ll
axes_ratio = height / width
aspect = axes_ratio / ax.get_data_ratio()
return aspect
返回的子图(对于图)。它有点微妙,因为它取决于显示尺寸和数据限制。 (这可能会导致混淆不同的比率,以及我认为让它易于访问很重要的原因。)
答案 0 :(得分:5)
从docs开始,纵横比是x轴和y轴中数据与显示比例单位的比率。即,如果在y方向上每个显示器有10个数据单元,在x方向上每个显示单元有1个数据单元,则该比率为1/10。圆圈的宽度比它高10倍。这对应于num
的一个方面执行以下操作的声明:
将拉伸圆圈,使得高度为宽度的num倍。 aspect = 1与aspect ='equal'相同。
基于您所看到的相同原始代码(matplotlib.axes._base.adjust_aspect
, starting around line 1405),我认为只要您只需要线性笛卡尔坐标轴的这个比率,我们就可以提出一个简化的公式。对于极轴和对数轴,事情变得复杂,所以我会忽略它们。
重申公式:
(x_data_unit / x_display_unit) / (y_data_unit / y_display_unit)
这恰好与
相同(y_display_unit / x_display_unit) / (y_data_unit / x_data_unit)
最后一个公式只是两个方向上的显示尺寸除以x和y限制的比率。请注意ax.get_data_ratio
NOT 在此处应用,因为它返回实际数据边界的结果,而不是轴限制:
from operator import sub
def get_aspect(ax):
# Total figure size
figW, figH = ax.get_figure().get_size_inches()
# Axis size on figure
_, _, w, h = ax.get_position().bounds
# Ratio of display units
disp_ratio = (figH * h) / (figW * w)
# Ratio of data units
# Negative over negative because of the order of subtraction
data_ratio = sub(*ax.get_ylim()) / sub(*ax.get_xlim())
return disp_ratio / data_ratio
现在让我们测试一下:
from matplotlib import pyplot as plt
fig, ax = plt.subplots()
ax.set_aspect('equal')
print('{} == {}'.format(ax.get_aspect(), get_aspect(ax)))
ax.set_aspect(10)
print('{} == {}'.format(ax.get_aspect(), get_aspect(ax)))
答案 1 :(得分:2)
我能找到的最好的事情是:
bbox
但令人惊讶的是,它变得非常复杂,我不确定它在转换等方面是否可靠,因为我对transform
和id
对象一无所知。
答案 2 :(得分:0)
怎么样
import numpy as np
aspect = sum(np.abs(ax.get_xlim())) / sum(np.abs(ax.get_ylim()))
答案 3 :(得分:0)
我不确定它是否完全符合您的要求,但是请尝试
bbox = axis.get_window_extent().transformed(figure.dpi_scale_trans.inverted())
aspect_ratio = bbox.width / bbox.height