plotly соотношение пропорции фигуры при увеличении
Рисую эллипс так, чтобы он выглядел как круг. Но при увеличении/уменьшении он теряет свои пропорции. Как сделать так чтобы увеличивалась только область прямоугольника с определенным соотношением сторон? Для решения пытался использовать scaleratio и scaleanchor, но вышла проблема что пределы по оси x смещаются и не могут быть настроены при помощи range.
import copy
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import numpy as np
def plot_pie_instead_of_a_marker(fig, x_points, y_points, pie_data, colors, sign, title, unit='',
text=None, norm_param=1, max_r=None, radius_by_par=None):
def degree2rad(degrees):
return degrees * np.pi / 180
def disk_part(center, radius, start_angle, end_angle, x_max, y_max, n_points=50):
t = np.linspace(degree2rad(start_angle), degree2rad(end_angle), n_points)
x = center[0] + radius * x_max * np.cos(t)
y = center[1] + radius * y_max * np.sin(t)
return np.append(x, (center[0], x[0])), np.append(y, (center[1], y[0]))
def distance(x1, y1, x2, y2):
return np.sqrt((x1 - x2)**2 + (y1 - y2)**2)
data = [[pie[i] for pie in pie_data] for i in range(0, len(x_points))]
q_liquid_max = max(pie_data[0] + pie_data[1])
min_dist = 1e6
x_max = max(x_points)
y_max = max(y_points)
for i in range(0, x_points.size):
x_dist_zero = distance(x_points[i] / x_max, y_points[i] / y_max, -0.1, y_points[i] / y_max)
if x_dist_zero < min_dist:
min_dist = x_dist_zero
y_dist_zero = distance(x_points[i] / x_max, y_points[i] / y_max, x_points[i] / x_max, -0.1)
if y_dist_zero < min_dist:
min_dist = y_dist_zero
for j in range(i + 1, y_points.size):
total_dist = distance(x_points[i] / x_max, y_points[i] / y_max, x_points[j] / x_max, y_points[j] / y_max)
if total_dist < min_dist:
min_dist = total_dist
max_r = min_dist * .5
max_r_liq = max_r
min_y, max_y = 1e3, 1
max_x = 0
min_x = 1e3
if max_r is None:
# r = min(min(abs(np.diff(x))), min(abs(np.diff(y)))) * .4 # вычисление радиуса круговой диаграммы
max_r = 0.05
if radius_by_par is None:
radius = np.full(len(x_points), max_r)
else:
radius = [max_r * i + 0.02 for i in radius_by_par / max(radius_by_par)]
sign_catalog = []
if text is not None:
sign = f'ID' + ': {0}<br>' + sign
for title_name in title:
s = copy.deepcopy(sign)
s = s + f'<br>{title_name}' + ': {3} ' + unit
sign_catalog.append(s)
for x, y, (a, b), id in zip(x_points, y_points, data, text):
r = (a + b) / q_liquid_max * max_r
ratio = a / (a + b)
for start_angle, end_angle, color, sign in zip(
(0, 360 * ratio), (360 * ratio, 359.9), colors, sign_catalog
):
if start_angle == 0:
name = sign.format(id, x, y, round(a * norm_param, 0))
else:
name = sign.format(id, x, y, round(b * norm_param, 0))
x_disk, y_disk = disk_part([x, y], r, start_angle, end_angle, x_max, y_max +40)
max_y = max(max(y_disk), max_y)
max_x = max(max(x_disk), max_x)
min_y = min(min(y_disk), min_y)
min_x = min(min(x_disk), min_x)
max_r_liq = max(r, max_r_liq)
fig.add_trace(
go.Scatter(
x=x_disk,
y=y_disk,
mode='lines',
fill="toself",
fillcolor=color,
line={"color": color},
name=name,
showlegend=False,
hoverinfo='text',
hovertext=name,
hoverlabel=dict(bgcolor="white", font_color="black")
)
)
fig.update_layout(
xaxis=dict(
range=[0, max_x]
),
yaxis=dict(
range=[min_y, max_y]
),
)
pie_1 = np.array([27.46, 8.95325436, 19.61, 10.25])
pie_2 = np.array([6.68, 0.21357491, 5.02, 0.18])
x = np.array([0.82639155, 0.19306054, 0.3007267, 0.81508946])
y = np.array([94.9698491, 147.00000000000003, 69.3, 57.6])
text = np.array(['1', '2', '3', '4'])
fig = make_subplots()
plot_pie_instead_of_a_marker(
fig,
x[y > 0],
y[y > 0],
pie_data=[
pie_1[y > 0],
pie_2[y > 0]
],
colors=['green', 'deepskyblue'],
sign='x1: {1: .2f}<br>y: {2:.2f} атм',
title=['a', 'b'],
unit='some_unit',
text=text[y > 0],
norm_param=1,
)
# Set the y-axis ranges and ratios
fig.update_layout(
yaxis=dict(
title='y1',
# scaleratio=fig.layout.xaxis.range[1] / fig.layout.yaxis.range[1],
# scaleanchor='x'
),
xaxis=dict(
range=fig.layout.xaxis.range,
# title='x',
scaleratio=fig.layout.yaxis.range[1] / fig.layout.xaxis.range[1],
scaleanchor='y',
)
)
fig.show()