【问题标题】:Plot data points with connecting lines but which leave gaps用连接线绘制数据点,但会留下间隙
【发布时间】:2015-07-29 15:14:16
【问题描述】:

我喜欢linespoints的绘图风格:
http://www.gnuplotting.org/join-data-points-with-non-continuous-lines/

但是,当我用这种样式绘制多条线时遇到了一个问题:

如您所见,第二系列点也将第一系列(线和点)空白,这是我不希望发生的。

使这成为可能的 gnuplot 功能是 pointintervalpointintervalbox

gnuplot 的文档:

pointinterval 的负值,例如-N,表示点符号 只为每第 N 个点绘制一个框(实际上是圆形) 通过填充 背景,每个点符号后面都被空白 颜色。命令set pointintervalbox控制这个半径 空白区域。它是默认半径的乘数,即 等于点大小。

http://www.bersch.net/gnuplot-doc/set-show.html#set-pointintervalbox

由于文档说,填充背景颜色,我希望使用 transparent 背景可以解决问题,但似乎使用了白色。

Gnuplot 版本

gnuplot> show version long

    G N U P L O T
    Version 5.0 patchlevel 0    last modified 2015-01-01 

    Copyright (C) 1986-1993, 1998, 2004, 2007-2015
    Thomas Williams, Colin Kelley and many others

    gnuplot home:     http://www.gnuplot.info
    faq, bugs, etc:   type "help FAQ"
    immediate help:   type "help"  (plot window: hit 'h')
Compile options:
-READLINE  +LIBREADLINE  +HISTORY  
-BACKWARDS_COMPATIBILITY  +BINARY_DATA  
+GD_PNG  +GD_JPEG  +GD_TTF  +GD_GIF  +ANIMATION  
-USE_CWDRC  +HIDDEN3D_QUADTREE  
+DATASTRINGS  +HISTOGRAMS  +OBJECTS  +STRINGVARS  +MACROS  +THIN_SPLINES  +IMAGE  +USER_LINETYPES +STATS +EXTERNAL_FUNCTIONS 

最小工作示例 (MWE):

gnuplot-space-line-mark-style.gp

reset
set terminal pngcairo transparent size 350,262 enhanced font 'Verdana,10'
show version
set output 'non-continuous_lines.png'
set border linewidth 1.5
set style line 1 lc rgb '#0060ad' lt 1 lw 2 pt 7 pi -1 ps 1.5
set style line 2 lc rgb '#0020ad' lt 1 lw 2 pt 7 pi -1 ps 1.5
set pointintervalbox 3
unset key
set ytics 1
set tics scale 0.75
set xrange [0:5]
set yrange [0:4]
plot 'plotting_data1.dat' with linespoints ls 1,\
     'plotting_data2.dat' with linespoints ls 2

plotting_data1.dat

# X   Y
  1   2
  2   3
  3   2
  4   1

plotting_data2.dat

# X   Y
  1.2   2.4
  2   3.5
  3   2.5
  4   1.2

更新

tex.stackoverflow.com 上提供了一个有效的pgfplots 解决方案

【问题讨论】:

  • 恐怕,gnuplot 没有解决方案。 Gnuplot 绘制每个点两次,一次使用背景颜色,一次使用原始颜色。如果 gnuplot 会尊重背景颜色是透明的,它也不会隐藏一个绘图的线条。要正确地做到这一点,必须更改 gnuplot 源以物理缩短线段,而不仅仅是对其进行重绘。所以这将是一个功能请求。
  • @Christoph:感谢您的评论。您是否碰巧知道实际上可以做到这一点的不同绘图软件?使用不同的透明层是可能的。我认为 pgfplots 可以做到这一点。
  • 不,不知道如何使用 pgfplots 或任何其他绘图软件。 pgfplots 可以做到这一点的机会非常高,所以你可以尝试在TeX.SX 询问。

标签: plot gnuplot transparency


【解决方案1】:

你可以用 gnuplot 做很多事情。这只是你允许它变得多么复杂的问题。 您可以通过两步绘图来实现差距。第一个:只有with points 和第二个:with vectors,它们是通过执行一些几何计算缩短的点之间的线。 参数L1决定了差距,需要根据数据和图表比例进行调整。使用 gnuplot 5.0 和 5.2 测试。

修订版:

这是创建与终端大小和图形比例无关的间隙的版本。它只需要更多的缩放。但是,由于它需要存储在GPVAL_...-variables 中的终端和图形的大小,您只能在 绘图后获得,因此不幸的是,该过程需要重新绘制。 我不确定这是否适用于所有终端。我刚刚在 wxt 终端上测试过。

经验发现(Win7 上的 wxt-terminal):

pointsize 100(ps)对应于600像素(px),因此:Rpxps=6(像素与点大小的比率)

term size 400,400(px)对应于8000,8000终端单位(tu),因此:Rtupx=20(终端单位与像素的比率)

编辑:对于不同的终端,Rtupx 的因素显然不同:wxt: 20qt: 10pngcairo: 1,您可以使用变量 GPVAL_TERM 来检查终端。

Rtupx = 1.                                   # for pngcairo terminal 1 tu/px
if (GPVAL_TERM eq "wxt") { Rtupx = 20. }     # 20 tu/px, 20 terminal units per pixel
if (GPVAL_TERM eq "qt")  { Rtupx = 10. }     # 10 tu/px, 10 terminal units per pixel

x 和 y 的轴单位 (au) 与终端单位 (tu) 的比率不同,分别是:

Rxautu = (GPVAL_X_MAX-GPVAL_X_MIN)/(GPVAL_TERM_XMAX-GPVAL_TERM_XMIN)
Ryautu = (GPVAL_Y_MAX-GPVAL_Y_MIN)/(GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)

变量GapSize 以磅为单位给出。实际上,real 间隙大小取决于点大小(以及线条的线宽)。为简单起见,这里的间隙大小是指从点的中心到直线起点的距离。因此,GapSize=1.5 在具有 pointsize 1.5 时将导致每侧出现 0.75 的间隙。早期版本中的L3(n) 现在在像素尺寸上被L3px(n) 替换,并且不再需要早期版本中的L1

代码:

### "linespoints" with gaps between lines and points
reset session

$Data1 <<EOD
# X   Y
  0   3
  1   2
  1.5 1
  3   2
  4   1
EOD

$Data2 <<EOD
   0    0
   1    1
   2    1
   2    2
   3    1
3.98 0.98
EOD

GapSize = 1.5
Rtupx = 20.      # 20 tu/px, 20 terminal units per pixel
Rpxps = 6.       # 6 px/ps,   6 pixels per pointsize
# Ratio: axis units per terminal units
Rxautu(n) = (GPVAL_X_MAX-GPVAL_X_MIN)/(GPVAL_TERM_XMAX-GPVAL_TERM_XMIN)
Ryautu(n) = (GPVAL_Y_MAX-GPVAL_Y_MIN)/(GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)

dXpx(n) = (x3-x0)/Rxautu(n)/Rtupx
dYpx(n) = (y3-y0)/Ryautu(n)/Rtupx
L3px(n) = sqrt(dXpx(n)**2 + dYpx(n)**2)

x1px(n) = dXpx(n)*GapSize*Rpxps/L3px(n)
y1px(n) = dYpx(n)*GapSize*Rpxps/L3px(n)
x2px(n) = dXpx(n)*(L3px(n)-GapSize*Rpxps)/L3px(n)
y2px(n) = dYpx(n)*(L3px(n)-GapSize*Rpxps)/L3px(n)

x1(n) = x1px(n)*Rtupx*Rxautu(n) + x0
y1(n) = y1px(n)*Rtupx*Ryautu(n) + y0
x2(n) = x2px(n)*Rtupx*Rxautu(n) + x0
y2(n) = y2px(n)*Rtupx*Ryautu(n) + y0

set style line 1 pt 7 ps 1.5 lc rgb "black"
set style line 2 lw 2 lc rgb "black 
set style line 3 pt 7 ps 1.5 lc rgb "red"
set style line 4 lw 2 lc rgb "red" 

plot \
    $Data1 u (x3=NaN, y3=NaN,$1):2 w p ls 1 notitle, \
    $Data1 u (y0=y3,y3=$2,x0=x3,x3=$1,x1(0)):(y1(0)): \
        (x2(0)-x1(0)):(y2(0)-y1(0)) w vectors ls 2 nohead notitle, \
    $Data2 u (x3=NaN, y3=NaN,$1):2 w p ls 3 notitle, \
    $Data2 u (y0=y3,y3=$2,x0=x3,x3=$1,x1(0)):(y1(0)): \
        (x2(0)-x1(0)):(y2(0)-y1(0)) w vectors ls 4 nohead notitle

replot
### end of code

结果:(两种不同的终端尺寸)

说明:

  • 问题:为什么L3(n)x1(n)y1(n)x2(n)y2(n)有参数(n)
    n在计算 L3(n),... 时始终为 0,并且不在右侧使用。
    答案: 使它们成为非常量表达式。或者,可以 添加x0,x3,y0,y3 作为变量,例如L3(x0, y0, x3, y3);然而 紧凑性会丢失。

  • 问题:plot $Data1 using (x3=NaN,y3=NaN,$1):2 中的using 部分是什么意思?
    答案: (,) 称为串行评估,记录在 gnuplot 文档中的 Expressions > Operator > Binary 部分 (仅 v4.4 或更新版本)。 串行评估仅出现在括号中,并保证 按从左到右的顺序进行。最右边子表达式的值 被退回。 这是为了初始化(x3,y3) 随后将线段绘制为向量。这无关紧要 点的绘制。

  • 问题:这是如何为 N 点绘制 N-1 段/向量的?
    答案: 在绘制点时设置 x3=NaN, y3=NaN 可确保对于 第一个数据点 初始数据点 (x0,y0) 设置为 (NaN,NaN) 这导致x1(0)y1(0) 的评估也返回NaN
    Gnuplot 通常会跳过带有NaN 的点,即第一个 数据点没有绘制矢量。代码在 迭代到达第二点时的第一点和第二点。

  • 问题:第二个plot '' u ... 如何遍历所有点?
    答案: gnuplot&gt; h special-filenames 解释了这一点:
    有一些文件名具有特殊含义:'''-''+''++'
    空文件名'' 告诉 gnuplot 在 相同的绘图命令。所以要从同一个输入文件中绘制两列:

              plot 'filename' using 1:2, '' using 1:3
    
  • 问题:我们需要在 (y1(0)) 周围加上括号吗?
    回答: gnuplot&gt; h using 解释如下:
    每个都可以是一个简单的列号,从一个中选择值 输入文件的字段,与第一个列标签匹配的字符串 数据集的行、括号中的表达式或特殊的 没有括在括号中的函数,例如 xticlabels(2)

【讨论】:

  • 我对您的回答有一些疑问。我已将它们添加到您的答案中,并由我自己提供初步答案。如果您有时间检查它们并在必要时进行更正,那就太好了。感谢您的精彩回答。 (Afaik,with vectors 风格自 gnuplot 4.2 以来就存在。)
  • 感谢您的编辑。好吧,我试图保持简短。您的所有问题都有助于更好地理解代码。你的答案都很好。是的,这是我在创建像 L3(n) 这样实际上独立于 n 的函数时想到的紧凑性。
  • 可以改进的一点是L1 对规模的依赖。理想情况下,它应该是独立于绝对 x 和 y 范围的相同视觉间隙。不知何故与点大小有关(以像素或屏幕单位或其他单位)。也许你有一些想法?
  • 确实可以改进。不幸的是,我也不知道解决方案。理想情况下,间隙应该随着点的大小而不是轴的比例缩放。当然,它不应该对 x 与 y 范围的比率敏感。 gnuplot中有不同的坐标系。 Afaik show variables all 不包含可用于计算字符单位偏移量的变量,然后将其转换为 x 轴和 y 轴的坐标系。
猜你喜欢
  • 1970-01-01
  • 2016-11-08
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多