我想实现以下三件事:
此时我的代码:
x = [9, 8, 11, 11, 14, 13, 16, 14, 14]
y = [9, 16, 15, 11, 10, 11, 10, 8, 8]
fig = plt.figure(figsize=(7,7), dpi=300)
axes = fig.add_axes([0,1,1,1])
axes.set_xlim(0, 17)
axes.set_ylim(0, 17)
axes.invert_yaxis()
axes.scatter(x, y, color='green')
axes.vlines(x, 0, y, linestyle="dashed", color='green')
axes.hlines(y, 0, x, linestyle="dashed", color='green')
axes.spines.right.set_visible(False)
axes.spines.bottom.set_visible(False)
plt.show()
视觉上:
还有我想实现的剧情
您可以通过在脊柱末端叠加三角形点来绘制箭头。
transforms
,但您也可以通过手动向 Axes
对象添加文本来创建标签。
可以通过 axes.annotate 来标记每个坐标,但您需要手动指定每个注释的位置,以确保它们不会与线条或其他注释重叠。
import matplotlib.pyplot as plt
from matplotlib.ticker import FixedLocator
x = [9, 8, 11, 11, 14, 13, 16, 14, 14]
y = [9, 16, 15, 11, 10, 11, 10, 8, 8]
fig = plt.figure(figsize=(7,7), dpi=300)
axes = fig.add_axes([.05,.05,.9,.9])
# Plots the data
axes.scatter(x, y, color='green')
axes.vlines(x, 0, y, linestyle="dashed", color='green')
axes.hlines(y, 0, x, linestyle="dashed", color='green')
axes.set_xlim(0, 17)
axes.set_ylim(0, 17)
axes.set_xticks(x)
axes.set_yticks(y)
axes.invert_yaxis()
# Move ticks to top side of plot
axes.xaxis.set_tick_params(
length=0, bottom=False, labelbottom=False, top=True, labeltop=True
)
axes.xaxis.set_tick_params(length=0)
# Add arrows to the spines by drawing triangle shaped points over them
axes.plot(1, 1, '>k', transform=axes.transAxes, clip_on=False)
axes.plot(0, 0, 'vk', transform=axes.transAxes, clip_on=False)
axes.spines[['bottom', 'right']].set_visible(False)
# Add labels for 0, F_1 and F_2
from matplotlib.transforms import offset_copy
axes.text(
0, 1, s='0', fontstyle='italic', ha='right', va='bottom',
transform=offset_copy(axes.transAxes, x=-5, y=5, fig=fig, units='points'),
)
axes.text(
1, 1, s='$F_1$', fontstyle='italic', ha='right', va='bottom',
transform=offset_copy(axes.transAxes, x=0, y=5, fig=fig, units='points'),
)
axes.text(
0, 0, s='$F_2$', fontstyle='italic', ha='right',
transform=offset_copy(axes.transAxes, x=-5, y=0, fig=fig, units='points'),
)
# Add labels at each point. Leveraging the alignment of the text
# AND padded offset.
lc = ('top', 'center', 0, -5)
ll = ('top', 'right', -5, -5)
lr = ('top', 'left', 5, -5)
ur = ('bottom', 'left', 5, 5)
alignments = [lc, lc, lc, ll, lc, ll, lc, ur, lr]
for i, (xc, yc, (va, ha, padx, pady)) in enumerate(zip(x, y, alignments)):
axes.annotate(
xy=(xc, yc), xytext=(padx, pady),
text=f'$F(x_{i})$', ha=ha, va=va, textcoords='offset points')
plt.show()
添加
axes.plot(1, 0, ">k", transform=axes.get_yaxis_transform(), clip_on=False)
axes.plot(0, 0, "vk", transform=axes.get_xaxis_transform(), clip_on=False)
会为你做的。这基本上只是标记的作弊图。
还有
from mpl_toolkits.axisartist.axislines.AxesZero
这允许
for direction in ["xzero", "yzero"]:
# adds arrows at the ends of each axis
ax.axis[direction].set_axisline_style("-|>")
但是他们无法使用默认设置处理您的情况下的反向 y 轴。
在寻找一种在轴上制作箭头的方法时遇到了这个问题,但我想控制箭头的纵横比,您可以使用上面的答案进行稍微修改。
您定义 (a) 一个
Affine2D
缩放变换 (mpl.transforms.Affine2D().scale(sx,sy)
) 并 (b) 使用该变换 (MarkerStyle
) 来使用 mpl.markers.MarkerStyle()
。此变换独立于使用轴坐标的坐标变换(例如 ax.get_xaxis_transform()
)。对每个轴执行一次此操作。请参阅此页面例如。
带有 2:1 长度:宽度箭头的示例:
# Arrows on axes
# We'll stretch out the triangular markers
stretchxax = mpl.transforms.Affine2D().scale(sx=2.,sy=1.)
stretchyax = mpl.transforms.Affine2D().scale(sx=1.,sy=2.)
ax.plot(1,0,'k',marker=mpl.markers.MarkerStyle('>',transform=stretchxax),transform=ax.get_yaxis_transform(),clip_on=False)
ax.plot(0,1,'k',marker=mpl.markers.MarkerStyle('^',transform=stretchyax),transform=ax.get_xaxis_transform(),clip_on=False)