python plt.text 中的重叠,包 adjustment_text 不起作用,如何修复它?

问题描述 投票:0回答:1

我有两个名为“freq”和“freq1000”的 pandas 数据框对象,每个对象都是由 5 个数字组成的向量。我想将它们绘制在同一个图表上,并在图表上显示 plt.text 以显示 y 值。 'freq' 和 'freq1000' 由 'pr' 和 'pr1000' 构造而成,两者都是由极其冗长的过程生成的。为了避免 plt.text 重叠,我点击链接如何修复重叠注释/文本并安装了包 adjustment_text。然而它并没有按照我想要的方式工作,并且我得到的图表仍然与图表上的数字重叠,请参见下图:

enter image description here

我的相关导入和代码包含在下面

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))

如何修复代码以解决重叠问题?谢谢!

python matplotlib text charts
1个回答
0
投票

这是一种重叠较少的尝试,但如果事情移动频繁,则需要进行一些调整。

ax.annotate
完成了大部分工作,但还有一些填充参数需要额外调整。主要思想是将蓝色标签向右移动,将橙色标签向左移动。

其中一个橙色标签与该线重叠。如果需要一次性绘图,您可以手动强制关闭它,但我没有这样做,是为了使答案对新案例更具普遍性和鲁棒性。

enter image description here

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)

这是一种替代安排,重叠的可能性较小。每个图都有一个视觉指南,但数字分为两个图。

enter image description here

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')
© www.soinside.com 2019 - 2024. All rights reserved.