Решение проблемы
«Нелинейная регрессия» с несколькими приблизительными значениями в интервале (1,2,5) дала мне:
y=a*x^2+b*x+c
a=0.25
b=-1.29
c=1.09
Попробуйте использовать:
cax = divider.append_axes('right', size='5%', pad=0.25*aspect**2-1.29*aspect+1.09)
Пока вы не можете использовать None
в качестве аспекта, когда aspect=1
, и вам не нужно передавать pad
. Кроме того, эта формула работает для aspect>=1
, вам может потребоваться получить другую формулу для значений меньше 1, потому что поведение действительно отличается. Для значений выше 2,5 вам нужно вычислить новые коэффициенты (объяснение ниже).
def plot_data(data, aspect, pad=None):
if aspect == None:
aspect = 1
fig, ax = plt.subplots()
img = ax.imshow(data, aspect=aspect)
last_axes = plt.gca()
divider = make_axes_locatable(ax)
cax = divider.append_axes('right', size='5%', pad=0.25*aspect**2-1.29*aspect+1.09)
cbar = fig.colorbar(img, cax=cax)
plt.sca(last_axes)
О «нелинейной регрессии»
Чтобы получить коэффициенты, первое, что мне нужно было сделать это получить несколько пар (аспект, отступы). Как получить их? Метод проб и ошибок: первая пара - оригинал (1,05), остальные были визуально хороши: (1,5, -0,305), (2, -0,48), (2,5, -0,58). Если вы видите, что в данных нет никакой линейности, но давайте в любом случае построим график
import matplotlib.pyplot as plt
data = [(1,0.05),(1.5,-0.305),(2,-0.48),(2.5,-0.58)]
plt.plot(*zip(*data))
plt.plot(*zip(*data),'or')
plt.xlabel("aspect")
plt.ylabel("padding")
plt.show()
![aspect/padding](https://i.stack.imgur.com/gDZoA.png)
Теперь давайте получим коэффициенты, делающие кривую примерка:
fit = np.polynomial.polynomial.Polynomial.fit(*zip(*pairs),2)
c,b,a = fit.convert().coef
(Да, я только подгонял кривую с полиномом второй степени, извините!) Различия между значениями, которые я изначально написал, и значением, полученным python, возникают из-за того, что я использовал другое программное обеспечение и я сделал округление до 2 десятичных знаков в большинстве случаев.
Почему я использовал полином второй степени (fit (x, y, 2))? Я пытался сделать модель максимально простой.
pairs = [(1,0.05),(1.5,-0.305),(2,-0.48),(2.5,-0.58)]
x = np.linspace(1,2.5,100)
yp = [a*x**2+b*x+c for x in x]
plt.plot(*zip(*pairs),'or', label='pairs')
plt.plot(x,yp,'g', label='Curve fitting')
plt.xlabel("aspect")
plt.ylabel("padding")
plt.legend(loc="upper right")
plt.show()
![Plot of the fitted curve](https://i.stack.imgur.com/BLSoh.png)
Работает ли это для значений за пределами [1,2.5]? На самом деле, нет. Для этого вы должны включить больше точек в аппроксимацию кривой, возможно, измените полином порядка 2, скажем, на логарифмический c один.
![enter image description here](https://i.stack.imgur.com/TO7eD.png)