我有两个pandas pandas rame对象,名为"freq"和"freq How to fix overlapping annotations / text0",每个对象都是5个数字的载体.我想将它们绘制在同一个图表上,并在图表上使用plt.text来显示y值."freq"和"freq How to fix overlapping annotations / text0"是从"pr"和"prHow to fix overlapping annotations / text0"构建的,两者都是通过极其冗长的过程生成的.为了避免plt.text重叠,我遵循链接How to fix overlapping annotations / text并安装了包adjust_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))

我应该如何修复代码来解决重叠问题?谢谢!

推荐答案

这是对重叠较少的try ,但如果事情发生很大变化,则需要进行一些调整.ax.annotate完成了大部分工作,但有一些填充参数可用于额外调整.主要 idea 是将蓝色标签向左移动,将橙色标签向右移动.

其中一个橙色标签与线重叠.如果需要一次性情节,您可以手动强制关闭它,但我没有这样做,以便使答案更通用且对新 case 更稳健.

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=(6, 3))
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 x, y in zip(pr_x, pr_y):
    ax.annotate(
        f'{y:.3f}', (x, y),
        xytext=(-0.6, 0), textcoords='offset fontsize', #shift blue pts left
        horizontalalignment='right', verticalalignment='center',
        weight='bold', fontsize=8, color=color_pr,
    )
    
for x, y in zip(pr1000_x, pr1000_y):
    ax.annotate(
        f'{y:.3f}', (x, y),
        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)

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

我认为,如果您有兴趣进一步探索这种安排,seabornFacetGrid可以用更少的代码来完成类似的事情.

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

Python相关问答推荐

Pandas 滚动操作

Inquirer库不适用于Pyterfly

如何推迟对没有公钥的视图/表的反射?

在Python中根据id填写年份系列

CustomTKinter-向表单添加额外的输入字段

如何将Matplotlib的fig.add_axes本地坐标与我的坐标关联起来?

在编写要Excel的数据透视框架时修复标题行

NumPy中的右矩阵划分,还有比NP.linalg.inv()更好的方法吗?

Python plt.text中重叠,包adjust_text不起作用,如何修复?

如何根据另一列值用字典中的值替换列值

Pandas实际上如何对基于自定义的索引(integer和非integer)执行索引

根据在同一数据框中的查找向数据框添加值

ModuleNotFound错误:没有名为flags.State的模块; flags不是包

通过pandas向每个非空单元格添加子字符串

Python键入协议默认值

如何请求使用Python将文件下载到带有登录名的门户网站?

在vscode上使用Python虚拟环境时((env))

Python+线程\TrocessPoolExecutor

Tkinter菜单自发添加额外项目

使用特定值作为引用替换数据框行上的值