Below is some demo code that illustrates the problem. In brief, I have annotation text of different length that is rotated to be in alignment with lines originating from the origin.
I want to be able to specify the precise position so that the text touches a specific circle. At present, the text is centered on the coordinate. When I try adjusting the coordinate for the length of the text, it remains inconsistent.
Would greatly appreciate any suggestions!
from plotly.offline import iplot
import numpy
r_2_d = numpy.pi / 180
d_2_r = numpy.pi
def polar_2_cartesian(θ, radius):
radians = θ * r_2_d
x = numpy.cos(radians) * radius
y = numpy.sin(radians) * radius
return x, y
def get_annotation(theta, radius, text, pad=0.1):
radius = radius + pad
if 90 < theta <= 270:
textangle = 180 - theta
else:
textangle = 360 - theta
x, y = polar_2_cartesian(theta, radius)
result = dict(x=x,
y=y,
textangle=textangle,
text=text,
showarrow=False,
font=dict(size=16),
xanchor='center',
yanchor='middle')
return result
text = ['one', 'something longer', 'single', 'middle', 'AB']
length = 2
lengths = [length] * len(text)
num_tips = len(lengths)
degree_sep = 360 / num_tips
cum_degree = [i * degree_sep for i in range(1, num_tips + 1)]
# make sure figure has 1/1 aspect
scale = 2
scatter = dict(type='scatter', x=[], y=[])
layout = dict(annotations=[],
width=800, height=800,
xaxis=dict(range=[-length*scale, length*scale]),
yaxis=dict(range=[-length*scale, length*scale]))
for θ, radius, txt in zip(cum_degree, lengths, text):
x, y = polar_2_cartesian(θ, radius)
scatter['x'].extend([0, x, None])
scatter['y'].extend([0, y, None])
a = get_annotation(θ, radius, txt, pad=0)
layout['annotations'].append(a)
markers = dict(type='scatter', x=[0.74, 1.06], y=[0, 0], mode='markers')
iplot(dict(data=[scatter], layout=layout))