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

如何在Makie中通过点击选择线条并显示对应编号?

Makie点击线条显示对应编号的问题解决

问题描述

我需要实现点击Makie绘图中的任意线条,在屏幕上显示该线条的编号。参照Makie官方教程的点拾取章节编写代码后,点击线条时显示的数字既不是预期的线条编号,也不是点击点坐标,完全不清楚这些数字的含义。

注:这是后续实现系列图(series)和拓扑图(topoplots)交互的基础,必须先解决这个基础问题。

原始代码

f = Figure(backgroundcolor = RGBf(0.98, 0.98, 0.98), resolution = (1500, 700))
ax = Axis(f[1, 1], xlabel = "Time [s]", ylabel = "Voltage amplitude [µV]") 

N = 1:length(pos)
positions = Observable(rand(Point2f, 10))

xs = 0:0.01:10
ys = 0.5 .* sin.(xs)

lines!(xs, ys)
lines!(xs, ys * 2)

hidedecorations!(ax, label = false, ticks = false, ticklabels = false) 
hidespines!(ax, :t, :r) 
hlines!(0, color = :gray, linewidth = 1)
vlines!(0, color = :gray, linewidth = 1)

i = Observable(0)
on(events(f).mousebutton, priority = 2) do event
    if event.button == Mouse.left && event.action == Mouse.press
        plt, i[] = pick(f)
        str = lift(i -> "$(i)", i)
        text!(ax, 1, -0.5, text = str,  align = (:center, :center)) 
    end
end
f

问题现象

点击线条后显示的数字不符合预期,示例如下:
点击示例1
点击示例2

解决方案

问题原因

你用pick(f)得到的第二个返回值,是拾取到的数据点在该线条数据数组中的索引,并非线条的编号。同时每次点击都新建text!元素,会导致文本叠加,也是问题之一。

修改后的代码

要实现显示线条编号,需要给每个线条对象绑定标识,拾取时匹配对应编号,同时避免重复创建文本元素:

f = Figure(backgroundcolor = RGBf(0.98, 0.98, 0.98), resolution = (1500, 700))
ax = Axis(f[1, 1], xlabel = "Time [s]", ylabel = "Voltage amplitude [µV]") 

xs = 0:0.01:10
ys = 0.5 .* sin.(xs)

# 存储线条对象与对应编号
lines_list = []
push!(lines_list, (plt=lines!(xs, ys), id=1))
push!(lines_list, (plt=lines!(xs, ys * 2), id=2))

hidedecorations!(ax, label = false, ticks = false, ticklabels = false) 
hidespines!(ax, :t, :r) 
hlines!(0, color = :gray, linewidth = 1)
vlines!(0, color = :gray, linewidth = 1)

# 预先创建文本元素,仅更新内容不重复创建
current_id = Observable("")
text!(ax, 1, -0.5, text = current_id, align = (:center, :center))

on(events(f).mousebutton, priority = 2) do event
    if event.button == Mouse.left && event.action == Mouse.press
        plt, _ = pick(f)
        # 匹配拾取到的线条对应的编号
        for line in lines_list
            if line.plt === plt
                current_id[] = "线条编号: $(line.id)"
                break
            end
        end
    end
end
f

代码说明

  • 用lines_list存储每个线条对象和对应编号,方便后续匹配查找
  • 预先创建Observable类型的文本元素,每次点击仅更新内容,避免文本叠加
  • 拾取到线条对象后,遍历列表匹配对应编号,更新文本显示

这样点击不同线条时,就会正确显示对应的线条编号了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 03:41:32