如何在多图中显示鼠标坐标?

How to display mouse coordinates in multiplots?

在交互式终端中,例如与wxt或qt一样,gnuplot可以在终端的状态行上显示鼠标光标的坐标window。这在许多情况下很有用,并且适用于单图,但不适用于多图。 gnuplot 文档明确提到(检查 help mouse

Mousing is not available inside multiplot mode. When multiplot is completed using unset multiplot, then the mouse will be turned on again but acts only on the most recent plot within the multiplot (like replot does).

这有点遗憾,因为如果在多图环境下从不同的图形中快速读出一些数据值会很方便。

问题:有没有办法在multiplot环境中显示坐标?

从 gnuplot 5.4.0 开始有“实验”选项 set mouse mouseformat function string_valued_function(x, y)。检查 help mouseformat。 有了这个,你可以创建一些特殊的功能。您需要做的是:

  • 通过将 GPVAL_... 图形参数添加到字符串变量来记住每个图形的图形参数
  • 从最后一个图的x,y开始计算相应图的坐标

如果您有重叠的地块,脚本将显示后来添加的地块(位于“顶部”)的坐标。

所以,希望这对其他人也有用。不保证以下脚本没有错误。任何简化和更好的想法都将非常受欢迎。 理想情况下,这个多图鼠标坐标将在 gnuplot 本身中实现。

我注意到坐标的转换似乎并不“完美”,尽管我猜公式是正确的,例如将 x,y 鼠标坐标转换为终端像素坐标我在 wxt 640,480 终端中得到了从(-1 到 639)和(0 到 379)的范围。欢迎任何解释。

脚本:(需要 gnuplot>=5.4.0)

### display mouse cursor coordinates in multiplot
reset session
set term wxt size 640,480

set samples 11
f(x) = x
g(x) = exp(x)

GraphParams = ''
addGraphParams(logAxisX,logAxisY) = GraphParams.\
            sprintf(' "%g %g %g %g %g %g %g %g %g %g %g %g"', \
            GPVAL_X_MIN, GPVAL_X_MAX, GPVAL_TERM_XMIN, GPVAL_TERM_XMAX, \
            GPVAL_X_LOG, logAxisX, \
            GPVAL_Y_MIN, GPVAL_Y_MAX, GPVAL_TERM_YMIN, GPVAL_TERM_YMAX, \
            GPVAL_Y_LOG, logAxisY)

getGraphParam(graphNo,paramNo) = real(word(word(GraphParams,graphNo),paramNo))
getXmin(n)     = getGraphParam(n,1)
getXmax(n)     = getGraphParam(n,2)
getTXmin(n)    = getGraphParam(n,3)
getTXmax(n)    = getGraphParam(n,4)
getLogX(n)     = getGraphParam(n,5)
getLogAxisX(n) = int(getGraphParam(n,6))
getYmin(n)     = getGraphParam(n,7)
getYmax(n)     = getGraphParam(n,8)
getTYmin(n)    = getGraphParam(n,9)
getTYmax(n)    = getGraphParam(n,10)
getLogY(n)     = getGraphParam(n,11)
getLogAxisY(n) = int(getGraphParam(n,12))

getPlotIdx(x,y) = (plotIdx=NaN, sum [_i=1:words(GraphParams)] ( \
                   TermX(x)>=getTXmin(_i) && TermX(x)<=getTXmax(_i) && \
                   TermY(y)>=getTYmin(_i) && TermY(y)<=getTYmax(_i) ? plotIdx=_i : 0), plotIdx)
GraphX(n,x,y)   = (n==n ? real(TermX(x)-getTXmin(n))/(getTXmax(n)-getTXmin(n)) : NaN)
GraphY(n,x,y)   = (n==n ? real(TermY(y)-getTYmin(n))/(getTYmax(n)-getTYmin(n)) : NaN)

FirstX(x,y) = (_n=getPlotIdx(x,y), _n==_n ? getLogAxisX(_n) ? \
               getLogX(_n)**(GraphX(_n,x,y)*(log(getXmax(_n))/log(getLogX(_n)) - \
               log(getXmin(_n))/log(getLogX(_n))) + log(getXmin(_n))/log(getLogX(_n))) : \
               getXmin(_n) + GraphX(_n,x,y)*(getXmax(_n)-getXmin(_n)) : NaN)
FirstY(x,y) = (_n=getPlotIdx(x,y), _n==_n ? getLogAxisY(_n) ? \
               getLogY(_n)**(GraphY(_n,x,y)*(log(getYmax(_n))/log(getLogY(_n)) - \
               log(getYmin(_n))/log(getLogY(_n))) + log(getYmin(_n))/log(getLogY(_n))) : \
               getYmin(_n) + GraphY(_n,x,y)*(getYmax(_n)-getYmin(_n)) : NaN)

# take GPVAL_... from last plot
TermX(x) = GPVAL_TERM_XMIN + (x-GPVAL_X_MIN) * \
          (GPVAL_TERM_XMAX-GPVAL_TERM_XMIN)/(GPVAL_X_MAX-GPVAL_X_MIN)
TermY(y) = GPVAL_TERM_YMIN + (y-GPVAL_Y_MIN) * \
          (GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)/(GPVAL_Y_MAX-GPVAL_Y_MIN)

mouse(x,y) = sprintf("%g, %g",FirstX(x,y),FirstY(x,y))
set mouse mouseformat function mouse(x,y)

set multiplot

    set size   0.5,1.0
    set origin 0.0,0.0
    set grid x,y
    set key bottom right samplen 2
    plot [0:10] '+' u 1:(g()) w lp pt 7 lw 2 lc rgb "red" ti " x^2"
    GraphParams = addGraphParams(0,0)
    
    set size 0.37,0.45
    set origin 0.07, 0.5
    set logscale y
    set obj 1 rect from graph 0,0 to graph 1,1 fc "white" behind
    plot [0:10] '+' u 1:(g()) w lp pt 7 lw 2 lc rgb "red" ti " x^2"
    unset obj 1
    GraphParams = addGraphParams(0,1)
    
    set size   0.5,0.5
    set origin 0.5,0.5
    set logscale x 2
    set logscale y
    plot [0.5:100] '+' u (g()):1 w lp pt 7 lw 2 lc rgb "web-green" ti "x" 
    GraphParams = addGraphParams(1,1)

    set size   0.5,0.5
    set origin 0.5,0.0
    unset logscale x
    unset logscale y
    plot [1:10] '+' u 1:(f()) w lp pt 7 lw 2 lc rgb "web-green" ti "x" 
    GraphParams = addGraphParams(0,0)

unset multiplot
### end of code

结果:(来自 wxt 终端的屏幕截图)

注意移动的鼠标光标和状态行中的坐标,坐标位于各个图形之间的 (NaN,NaN)。