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

如何提取使用markevery参数绘制的折线中的标记数据点?

这个问题我太有共鸣了!之前用markevery做折线标记时,也踩过get_data()只返回全量数据的坑——毕竟get_data()是获取线条的原始数据源,而markevery只是绘图渲染阶段的筛选规则,根本不会修改底层存储的数据。

你提到用私有方法lines._mark_every_path()解决了问题,确实可行,但我们可以用更通用、更贴近规范的方式来获取标记点坐标,下面两种方案供你参考:

解决方法

方法一:借助matplotlib内部工具函数(推荐)

matplotlib内部有一个专门处理markevery索引计算的工具函数matplotlib.markers._get_markevery_indices,它是处理markevery规则的核心逻辑,比lines._mark_every_path更专注于索引筛选,不需要涉及路径绘制的额外逻辑。

示例代码:

import numpy as np
from matplotlib import pyplot as plt
import matplotlib.markers as markers

# 生成数据并绘制带markevery的折线
x = np.arange(100)
y = x**2
line, = plt.plot(x, y, marker='o', markevery=(0, 0.1))

# 获取markevery参数和数据总长度
markevery_config = line.get_markevery()
total_points = len(x)

# 计算标记点的索引
mark_indices = markers._get_markevery_indices(total_points, markevery_config)

# 提取标记点的坐标
mark_x = x[mark_indices]
mark_y = y[mark_indices]

# 验证:这里应该得到10个点(0,10,20...90)
print(len(mark_x))  # 输出10
assert len(mark_x) != 100

这个函数能处理所有合法的markevery参数类型(整数、浮点数、元组、索引列表等),完全遵循matplotlib的官方规则,稳定性很高,是目前最省心的方案。

方法二:自行实现markevery规则(无内部依赖)

如果你完全不想依赖下划线开头的内部函数,可以自己实现markevery的筛选逻辑,覆盖常见的参数场景:

import numpy as np

def calculate_markevery_indices(total_points, markevery):
    if isinstance(markevery, tuple):
        # 处理(start, step)形式的元组,支持比例或整数步长
        start, step = markevery
        if isinstance(step, float):
            # 比例步长转换为实际步长
            step = int(step * total_points)
        mark_indices = np.arange(start, total_points, step)
    elif isinstance(markevery, int):
        # 每N个点取一个
        mark_indices = np.arange(0, total_points, markevery)
    elif isinstance(markevery, float):
        # 按比例取点,比如0.1就是取10%的点
        point_count = int(total_points * markevery)
        mark_indices = np.linspace(0, total_points - 1, point_count).astype(int)
    elif isinstance(markevery, (list, np.ndarray)):
        # 直接传入的索引列表
        mark_indices = np.asarray(markevery)
    else:
        raise ValueError(f"不支持的markevery参数类型:{type(markevery)}")
    return mark_indices

# 使用示例
line, = plt.plot(np.arange(100)**2, marker='o', markevery=(0, 0.1))
x, y = line.get_data()
mark_indices = calculate_markevery_indices(len(x), line.get_markevery())
mark_x = x[mark_indices]
mark_y = y[mark_indices]

这种方式完全自主可控,不需要依赖matplotlib的内部实现,但需要注意:如果未来matplotlib更新了markevery的规则(比如新增了参数类型),你需要同步更新自己的函数逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:34:26