Matplotlib 如何在散点图中改进标签位置

Matplotlib 如何在散点图中改进标签位置

在使用matplotlib绘制散点图时,如果数据集比较大,我们需要在图中展示每一个点的标签信息,常常会遇到标签重叠或者有效信息被遮挡,使得图形难以读取的问题。本文将介绍一些方法,通过优化标签的位置,使图形变得清晰易读。

阅读更多:Matplotlib 教程

示例数据

我们将使用python内置库random创建模拟数据集进行演示。

import numpy as np
import random
import matplotlib.pyplot as plt

# 创建模拟数据
x = np.array(np.random.normal(loc=0, scale=10, size=100))
y = np.array(np.random.normal(loc=0, scale=10, size=100))
labels = [random.randint(1,20) for i in range(100)]
Python

绘制图形

fig, ax = plt.subplots(figsize=(10,8))
scatter = ax.scatter(x, y, c = labels)
ax.grid(True)
plt.show()
Python

1. 使用annotate方法

在matplotlib中,annotate方法可使标签在绘图中精确定位,同时可以跨越图形的各种元素(轴线、图形等)。对于大数据集,需要绘制很多标签时,这种方法尤其实用。
annotate方法最重要的两个参数是:xy和xytext。他们分别是被注释点和文本位置的坐标点。

fig, ax = plt.subplots(figsize=(10,8))
scatter = ax.scatter(x, y, c = labels)
ax.grid(True)

for i, txt in enumerate(labels):
    ax.annotate(txt, (x[i], y[i]), xytext=(5,5), textcoords='offset points', ha='left', va='top')

plt.show()
Python

我们可以看到,使用annotate方法能够精确的将标签放置到对应散点对应位置,不会产生重叠遮挡现象。

2. 调节字体大小

有时候,标签字体过大也是重复死算或者遮挡的原因之一。在matplotlib中,我们可以设置字体大小(fontsize)、对齐方式(ha、va)等参数,调节标签的字体大小,避免过大过小。

fig, ax = plt.subplots(figsize=(10,8))
scatter = ax.scatter(x, y, c = labels)
ax.grid(True)

for i, txt in enumerate(labels):
    ax.annotate(txt, (x[i], y[i]), xytext=(5,5), textcoords='offset points', ha='left', va='top', fontsize=8)

plt.show()
Python

我们可以看到,缩小标签字体大小后,图形更清晰易读。

3. 使用自适应的字体大小方法

当数据集较大时,自适应字体可以自动调整标签的字号,避免重叠遮挡。在使用这种方法之前,需要提前计算每个标签点的最优字体大小和位置,可以通过以下途径进行计算:

from matplotlib.font_manager import FontProperties

fp = FontProperties(size=8)
bbox_props = dict(boxstyle="round,pad=0.3", fc="#ddcaa7", ec="#496165", lw=1.5)
x, y = np.random.normal(size=[2, 100])
labels = [random.randint(1, 20) for i in range(100)]

fig, ax = plt.subplots(figsize=(10,8))
scatter = ax.scatter(x, y, c=labels)
ax.grid(True)

for i, txt in enumerate(labels):
    plt.text(x[i], y[i], str(txt), ha='center', va='center', fontproperties=fp, bbox=bbox_props)

plt.show()
Python

可以看到,标签字体大小自适应,同时也能很好地避免标签之间的重叠现象。

4. 使用offsetbox方法

使用offsetbox方法,可以将标签放置在散点周围的固定位置,可以保证标签在不重叠的前提下完整显示,同时不需要手动调整字体大小。

from matplotlib.offsetbox import OffsetImage, AnnotationBbox

fig, ax = plt.subplots(figsize=(10,8))
scatter = ax.scatter(x, y, c = labels)
ax.grid(True)

def get_image(txt):
    return OffsetImage(txt, zoom=0.4)

 artists = []
for i, txt in enumerate(labels):
    ab = AnnotationBbox(get_image(txt), (x[i], y[i]), frameon=False, xybox=(5,5), boxcoords="offset points", ha='left')
    artists.append(ax.add_artist(ab))

plt.show()
Python

我们可以看到,使用offsetbox方法能够在不重叠的前提下完整显示标签,同时标签也不会遮挡数据点。

总结

本文介绍了四种在matplotlib中优化标签位置的方法,前三种方法需要手动调整标签位置或字体大小,而第四种方法需要使用特定的工具和技巧,但可以完全自动化。根据需求不同可以选择不同的方法,使图形更加清晰、易读。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册