You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在散点图周围均匀排布标注图像框?

散点图图像标注环形排布优化

我需要给散点图的每个数据点添加图像标注,但默认设置下图像会重叠,还会遮挡坐标轴、图例等关键元素。目标是让这些图像以圆形的形式排布在主散点图的外围。

当前使用的代码如下:

import matplotlib.cbook as cbook
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
import seaborn as sns

#Generate n points around a 2d circle
def generate_circle_points(n, centre_x, center_y, radius=1):
    """Generate n points around a circle.
    Args:
        n (int): Number of points to generate.
        centre_x (float): x-coordinate of circle centre.
        center_y (float): y-coordinate of circle centre.
        radius (float): Radius of circle.
    Returns:
        list: List of points.
    """

    points = []
    for i in range(n):
        angle = 2 * np.pi * i / n
        x = centre_x + radius * np.cos(angle)
        y = center_y + radius * np.sin(angle)
        points.append([x, y])

    return points

fig, ax = plt.subplots(1, 1, figsize=(7.5, 7.5))

data = pd.DataFrame(data={'x': np.random.uniform(0.5, 2.5, 20),
                          'y': np.random.uniform(10000, 50000, 20)})

with cbook.get_sample_data('grace_hopper.jpg') as image_file:
    image = plt.imread(image_file)

# Set logarithmic scale for x and y axis
ax.set(xscale="log", yscale='log')
# Add grid
ax.grid(True, which='major', ls="--", c='gray')

coordianates = generate_circle_points(n=len(data),
                                      centre_x=0, center_y=0, radius=10)

# Plot the scatter plot
scatter = sns.scatterplot(data=data, x='x', y='y', ax=ax)
for index, row in data.iterrows():

    imagebox = OffsetImage(image, zoom=0.05)
    imagebox.image.axes = ax
    xy = np.array([row['x'], row['y']])
    xybox = np.array(coordianates[index])
    ab = AnnotationBbox(imagebox, xy,
                        xycoords='data',
                        boxcoords="offset points",
                        xybox=xybox,
                        pad=0)

    ax.add_artist(ab)

问题分析

当前代码的核心问题在于:

  • 环形坐标生成时使用了数据坐标系的(0,0),但散点图的x/y轴是对数尺度,该点不在可视范围内
  • boxcoords="offset points"设置让环形坐标成为数据点的偏移量,而非围绕图中心的绝对位置

解决方案

要实现图像围绕图中心排布,需要切换到轴坐标系生成环形位置,并调整标注的坐标参数:

修改后的完整代码:

import matplotlib.cbook as cbook
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
import seaborn as sns

def generate_circle_points(n, centre_x=0.5, center_y=0.5, radius=0.35):
    """基于轴坐标系生成环形点,轴坐标系范围[0,1]对应整个绘图区域"""
    points = []
    for i in range(n):
        angle = 2 * np.pi * i / n
        x = centre_x + radius * np.cos(angle)
        y = center_y + radius * np.sin(angle)
        points.append([x, y])
    return points

fig, ax = plt.subplots(1, 1, figsize=(7.5, 7.5))

data = pd.DataFrame(data={'x': np.random.uniform(0.5, 2.5, 20),
                          'y': np.random.uniform(10000, 50000, 20)})

with cbook.get_sample_data('grace_hopper.jpg') as image_file:
    image = plt.imread(image_file)

ax.set(xscale="log", yscale='log')
ax.grid(True, which='major', ls="--", c='gray')

# 基于轴坐标系生成环形坐标,半径适配图尺寸
coordianates = generate_circle_points(n=len(data))

scatter = sns.scatterplot(data=data, x='x', y='y', ax=ax)

for index, row in data.iterrows():
    imagebox = OffsetImage(image, zoom=0.05)
    imagebox.image.axes = ax
    
    # 数据点坐标(数据坐标系)
    xy_data = (row['x'], row['y'])
    # 图像环形位置(轴坐标系)
    xy_image = coordianates[index]
    
    # 创建标注:图像固定在轴坐标系的环形位置,连线到对应数据点
    ab = AnnotationBbox(imagebox, xy_data,
                        xycoords='data',
                        boxcoords='axes fraction',
                        xybox=xy_image,
                        pad=0.3,
                        arrowprops=dict(arrowstyle="-", color='gray', lw=0.8))
    
    ax.add_artist(ab)

plt.tight_layout()
plt.show()

修改说明

  1. 环形坐标生成:改用轴坐标系的(0.5,0.5)作为中心,半径设为0.35,确保图像分布在绘图区域外围
  2. 坐标系统切换:boxcoords='axes fraction'让图像位置不受数据尺度影响,固定在图的环形区域
  3. 添加关联连线:通过arrowprops添加灰色连线,将图像与对应数据点关联,同时避免遮挡主图元素
  4. 调整间距:增加pad值防止图像之间重叠

内容的提问来源于stack exchange,提问作者Harold Grosjean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 16:20:38