I have a scatter plot + annotation like this:
I annotated each dot with this code:
for i, txt in enumerate(labels):
ax.annotate(txt, (x[i], y[i]),
fontproperties=cur_font,
ha='center',
va='top',
fontsize=14)
As you can see from the figure about, the text overlaps with the pie chart. I can do y[i] - 0.05
to hack around this issue. But I would like to know if there is a way to automatically calculate the 0.05
part so that the code adapts to any x & y input.
Code for drawing the circles:
draw_scatter_pie
is called first, then it calls draw_pie
to draw each pie chart.
def draw_pie(
dist: List[float], xpos: float, ypos: float, size: float, ax # pie各个slice的大小占比
) -> None:
# for incremental pie slices
cumsum = np.cumsum(dist)
cumsum = cumsum / cumsum[-1]
pie = [0] + cumsum.tolist()
counter = 0
# draw each pie slices
# for my data, there are only two slices for each pie chart
for r1, r2 in zip(pie[:-1], pie[1:]):
angles = np.linspace(2 * np.pi * r1, 2 * np.pi * r2)
x = [0] + np.cos(angles).tolist()
y = [0] + np.sin(angles).tolist()
xy = np.column_stack([x, y])
ax.scatter(
xpos,
ypos,
marker=xy,
s=size,
facecolor=("indigo" if counter == 0 else "#CDCDCD"),
)
counter += 1
def draw_scatter_pie(
x: List[float],
y: List[float],
pie_size: List[float],
labels: List[str],
size: float,
display_axis=True,
adjust_y = 0
) -> None:
fig, ax = plt.subplots(figsize=(12, 10))
for i in range(len(x)):
# for my data, there are only two slices for each pie chart
p_size = [pie_size[i], 1 - pie_size[i]]
draw_pie(p_size, x[i], y[i], size, ax)
for i, txt in enumerate(labels):
ax.annotate(
txt,
(x[i], y[i] - adjust_y), # want to adjust the y position of each annotation
fontproperties=cur_font,
ha="center",
va="top",
fontsize=14,
)
ax.axes.get_xaxis().set_visible(display_axis)
ax.axes.get_yaxis().set_visible(display_axis)
plt.show()