我有两个名为“freq”和“freq1000”的 pandas 数据框对象,每个对象都是由 5 个数字组成的向量。我想将它们绘制在同一个图表上,并在图表上显示 plt.text 以显示 y 值。 'freq' 和 'freq1000' 由 'pr' 和 'pr1000' 构造而成,两者都是由极其冗长的过程生成的。为了避免 plt.text 重叠,我点击链接如何修复重叠注释/文本并安装了包 adjustment_text。然而它并没有按照我想要的方式工作,并且我得到的图表仍然与图表上的数字重叠,请参见下图:
我的相关导入和代码包含在下面
import pandas as pd
import matplotlib.pyplot as plt
from adjustText import adjust_text
freq = pd.DataFrame(np.average(pr, axis=0), index=pr.columns)
freq1000 = pd.DataFrame(np.average(pr1000, axis=0), index=pr1000.columns)
plt.plot(freq, label='n=500')
plt.plot(freq1000, label='n=1000')
plt.legend(loc='best')
plt.xlabel('x')
plt.ylabel('y')
plt.title('curve high vs low,gtype{}'.format(type_))
# plt.close()
texts=[]
for x, y in zip(freq.index, freq.values):
texts.append(plt.text(x, y,'%.3f' % y))
adjust_text(texts, only_move={'points':'y', 'texts':'xy'}, arrowprops=dict(arrowstyle="->", color='r', lw=0.5))
texts=[]
for x, y in zip(freq1000.index, freq1000.values):
texts.append(plt.text(x, y,'%.3f' % y))
adjust_text(texts, only_move={'points':'y', 'texts':'y'}, arrowprops=dict(arrowstyle="->", color='r', lw=0.5))
如何修复代码以解决重叠问题?谢谢!
这是一种重叠较少的尝试,但如果事情移动频繁,则需要进行一些调整。
ax.annotate
完成了大部分工作,但还有一些填充参数需要额外调整。主要思想是将蓝色标签向右移动,将橙色标签向左移动。
其中一个橙色标签与该线重叠。如果需要一次性绘图,您可以手动强制关闭它,但我没有这样做,是为了使答案对新案例更具普遍性和鲁棒性。
from matplotlib import pyplot as plt
pr_x = [-1, -0.5, 0, 0.5, 1]
pr_y = [1, 0.683, 0.067, 0.5, 1]
color_pr = 'tab:blue'
pr1000_x = [-1, -0.5, 0, 0.5, 1]
pr1000_y = [1, 0.983, 0.05, 0.917, 1]
color_pr1000 = 'tab:orange'
f, ax = plt.subplots(figsize=(5, 5))
ax.plot(pr_x, pr_y, color=color_pr, marker='o', label='n=500')
ax.plot(pr1000_x, pr1000_y, color=color_pr1000, marker='o', label='n=1000')
ax.set(xlabel='x', ylabel='y', title='curve high vs low, gtype2')
ax.legend()
for xy in zip(pr_x, pr_y):
ax.annotate(
f'{y:.3f}', xy,
xytext=(-0.6, 0), textcoords='offset fontsize', #shift blue pts left
horizontalalignment='right', verticalalignment='center',
weight='bold', fontsize=8, color=color_pr,
)
for xy in zip(pr1000_x, pr1000_y):
ax.annotate(
f'{y:.3f}', xy,
xytext=(0.6, 0.2), textcoords='offset fontsize', #shift orange pts up, right
horizontalalignment='left', verticalalignment='bottom',
weight='bold', fontsize=8, color=color_pr1000,
# rotation=20
)
ax.set_xlim(ax.get_xlim()[0] * 1.15, ax.get_xlim()[1]) #make x axis wider
ax.spines[['right', 'top']].set_visible(False)
这是一种替代安排,重叠的可能性较小。每个图都有一个视觉指南,但数字分为两个图。
f, axs = plt.subplots(ncols=2, nrows=1, figsize=(7, 3), sharey=True, layout='tight')
pr_data = (pr_x, pr_y, 'n=500')
pr1000_data = (pr1000_x, pr1000_y, 'n=1000')
for ax in axs:
fg_data = pr_data if ax==axs[0] else pr1000_data
bg_data = pr_data if ax==axs[1] else pr1000_data
#Foreground data
x, y, label = fg_data
ax.plot(x, y, 'tab:purple', marker='o', markersize=7, linewidth=3, label=label)
for x_i, y_i in zip(x, y):
ax.annotate(
f'{y_i:.3f}', (x_i, y_i), xytext=(1, 0.6), textcoords='offset fontsize',
horizontalalignment='left', verticalalignment='top',
color='midnightblue', weight='bold', size=8, rotation=0,
)
#Background data
x, y, label = bg_data
ax.plot(x, y, 'black', marker='o', markersize=6,
linewidth=4.5, linestyle='-', alpha=0.12,
label=label, zorder=0)
ax.set_xlabel('x')
ax.spines[['right', 'top']].set_visible(False)
ax.set_title(label, color='rebeccapurple', weight='bold')
# ax.legend()
axs[0].set_ylabel('y')