[英]update an artiste (Line2D) on a figure without re-drawing the whole figure - axes.draw_artist() crashes
[英]Draw a line on a figure with multiple axes
我創建了一個具有多個軸的圖形,並將 AnchoredText 添加到其中一些軸。 這個 AnchoredText 就像一個 label,它將它所在的軸連接到一個外軸,如下所示:
[示例圖片]
我試過像這樣使用 AnnnotationBbox:
from matplotlib import pyplot as plt
from matplotlib.offsetbox import AnchoredText, AnnotationBbox, TextArea
fig_width = 16
fig_height = 9
fig = plt.figure(figsize=(fig_width, fig_height))
fig.add_axes(
(0, 0, 1, 1),
alpha=1,
xticks=[],
yticks=[],
)
fig.get_axes()[-1].set_xlim(0, fig_width)
fig.get_axes()[-1].set_ylim(0, fig_height)
fig.add_axes(
(0.66, 0.225, 0.075, 0.025),
label="L1",
alpha=1,
xticks=[],
yticks=[],
)
axis = fig.get_axes()[-1]
axis.set_xlim(
fig_width * 0.66, fig_width * (0.66 + .075)
)
axis.set_ylim(
fig_height * .225, fig_height * (.225 + .025)
)
circle = AnchoredText(
s="L1",
frameon=False,
loc="upper left",
prop=dict(bbox=dict(boxstyle="circle")),
)
axis.add_artist(circle)
fig.add_axes(
(0.62, 0.28, 0.03, 0.04),
label="L2",
alpha=1,
xticks=[],
yticks=[],
)
axis = fig.get_axes()[-1]
axis.set_xlim(
fig_width * 0.62, fig_width * (0.62 + .03)
)
axis.set_ylim(
fig_height * .28, fig_height * (.28 + .04)
)
def get_axes(fig, name):
for ax in fig.axes:
label = ax.get_label()
if label == name:
return ax
l1 = get_axes(fig, "L1") # Gets axis with given label
l2 = get_axes(fig, "L2")
offsetbox = TextArea("Test")
# Get the top outer limit of the l2 axis
xlim = (l2.get_xlim()[0] + l2.get_xlim()[1]) / 2
ylim = l2.get_ylim()[1]
xy = [xlim, ylim]
# Approximating the coordinates of AnchoredText
xlim2 = l1.get_xlim()[0] * 0.25
ylim2 = l1.get_ylim()[0] * 0.75
xy2 = [xlim2, ylim2]
ab = AnnotationBbox(
offsetbox,
xy2,
xybox=xy,
xycoords="data",
boxcoords=("axes fraction", "data"),
box_alignment=(0.0, 0.5),
arrowprops=dict(arrowstyle="-"),
)
l1.add_artist(ab)
plt.show()
運行上面的代碼不會在我的圖中添加該行,我不確定為什么。 有沒有更好的方法來解決這個問題? 如果有的話,我怎樣才能獲得 AnchoredText 的限制?
這是刺傷它。 訣竅是 plot 一個通用空白(和透明)軸中的子圖,然后 plot 一條連接子圖的線。
from matplotlib import pyplot as plt
from matplotlib.offsetbox import AnchoredText
# Initialize figure
fig, ax_canvas = plt.subplots(figsize=(12, 6), constrained_layout=True)
# Set order of drawing, Ax canvas will be the last one so that the line connecting the other plots is on top
ax_canvas.set_zorder(10)
# Hide the main axis to set our blank canvas
ax_canvas.set_axis_off()
# Make background transparent so that it does not cover other plots when we draw the connecting line
ax_canvas.patch.set_facecolor('None')
ax_canvas.patch.set_visible(False)
# Set dimensions so it's easier to plot the line correctly
ax_canvas.set_xlim([0, 1])
ax_canvas.set_ylim([0, 1])
# First subplot axes in the canvas
left1, bottom1, width1, height1 = [0.1, 0.5, 0.5, 0.4]
ax1 = fig.add_axes([left1, bottom1, width1, height1])
ax1.set_zorder(0)
ax1.set_xlim([0, 1])
ax1.set_ylim([0, 1])
ax1.text(0.5, 0.5, 'Ax 1')
# Add the circle
circle = AnchoredText(
s="L1",
frameon=False,
loc="upper left",
prop=dict(bbox=dict(boxstyle="circle")),
)
ax1.add_artist(circle)
# Second axes in the canvas
left2, bottom2, width2, height2 = [0.45, 0.15, 0.3, 0.2]
ax2 = fig.add_axes([left2, bottom2, width2, height2])
ax1.set_zorder(0)
ax2.set_xlim([0, 1])
ax2.set_ylim([0, 1])
ax2.text(0.5, 0.5, 'Ax 2')
# Line connecting Ax1 and Ax2 in the Ax canvas
# The values below are eyeballed based on the ax_canvas having x and y limits 0 to 1
# Roughly where the circle is in Ax1, x middle of Ax2
x_line = [0.125, 0.6]
# Roughly where the circle is in Ax1, height of Ax2
y_line = [0.87, 0.35]
ax_canvas.plot(x_line, y_line, c='k', ls='--')
plt.show()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.