在烛台图上的指定点显示标签

问题描述 投票:0回答:1

给出一个非常简单的烛台图:

$Data << EOD
2020-01-01,74.06,73.19,81.96,77.38
2020-02-01,76.08,64.09,81.81,68.34
2020-03-01,70.57,53.15,76.0,63.57
2020-04-01,61.63,59.23,73.63,73.45
2020-05-01,71.56,71.46,81.06,79.49
2020-06-01,79.44,79.3,93.1,91.2
2020-07-01,91.28,89.15,106.42,106.26
2020-08-01,108.2,107.89,131.0,129.04
2020-09-01,132.76,103.1,137.98,115.81
2020-10-01,117.64,107.72,125.39,108.86
2020-11-01,109.11,107.32,121.99,119.05
2020-12-01,121.01,120.01,138.79,132.69
2021-01-01,133.52,126.38,145.09,131.96
2021-02-01,133.75,118.39,137.88,121.26
2021-03-01,123.75,116.21,128.72,122.15
2021-04-01,123.66,122.49,137.07,131.46
2021-05-01,132.04,122.25,134.07,124.61
2021-06-01,125.08,123.13,137.41,136.96
2021-07-01,136.6,135.76,150.0,145.86
2021-08-01,146.36,144.5,153.49,151.83
2021-09-01,152.83,141.27,157.26,141.5
2021-10-01,141.9,138.27,153.17,149.8
2021-11-01,148.99,147.48,165.7,165.3
2021-12-01,167.48,157.8,182.13,177.57
2022-01-01,177.83,154.7,182.94,174.78
2022-02-01,174.01,152.0,176.65,165.12
2022-03-01,164.7,150.1,179.61,174.61
2022-04-01,174.03,155.38,178.49,157.65
2022-05-01,156.71,132.61,166.48,148.84
2022-06-01,149.9,129.04,151.74,136.72
2022-07-01,136.04,135.66,163.63,162.51
2022-08-01,161.01,157.14,176.15,157.22
2022-09-01,156.64,138.0,164.26,138.2
2022-10-01,138.21,134.37,157.5,153.34
2022-11-01,155.08,134.38,155.45,148.03
2022-12-01,148.21,125.87,150.92,129.93
2023-01-01,130.28,124.17,147.23,144.29
2023-02-01,143.97,141.32,157.38,147.41
2023-03-01,146.83,143.9,165.0,164.9
2023-04-01,164.27,159.78,169.85,169.68
2023-05-01,169.28,164.31,179.35,177.25
2023-06-01,177.7,176.93,194.48,193.97
2023-07-01,193.78,186.6,198.23,196.45
2023-08-01,196.24,171.96,201.73,187.87
2023-09-01,189.49,167.62,189.98,171.21
2023-10-01,171.22,165.67,182.34,170.77
2023-11-01,171.0,170.12,192.93,189.95
2023-12-01,190.33,187.45,196.62,192.53
EOD

set xdata time
set timefmt "%Y-%m-%d"
set datafile separator ","
set palette defined (-1 "red", 1 "green")
set style fill solid noborder
unset colorbox

unset border
unset xtics
unset ytics
set size 0.9,0.9
set bmargin at screen 0.1
set lmargin at screen 0.1

plot $Data using 0:2:3:4:5:($5 < $2 ? -1 : 1) with candlesticks palette notitle

我正在尝试创建 4 个标签:

  • 第一个打开值时有一个 (
    2020-01-01,74.06,73.19,81.96,77.38
    )
  • 最后收盘价为 1 (
    2023-12-01,190.33,187.45,196.62,192.53
    )
  • 具有最低值的烛台 (
    2020-03-01,70.57,53.15,76.0,63.57
    )
  • 以及具有最高值的烛台 (
    2023-08-01,196.24,171.96,201.73,187.87
    )

我从外部脚本传递数据,因此如果无法使用 gnuplot 计算它们,我可以提前知道这些点。

这是我想要实现的目标的粗略说明:

我正在努力解决的部分是指定 x 坐标,因为我正在处理时间数据。在这种情况下我应该如何继续指定 x 坐标?

另一个是正确偏移标签。对于图左侧和右侧的那些,我可以使用

left
right
偏移。但是我应该如何处理顶部和底部的那些呢?如何从顶部和底部偏移?

gnuplot
1个回答
0
投票

这是一个紧凑的 gnuplot-only 解决方案,它很简单,但可能需要一些解释。

虽然您可以通过

stats
提取最小值、最大值(检查
help stats
),但这里是在绘制数据期间完成的。此外,该脚本不使用
set xdata time
set timefmt ...
,而是使用
set format x ... timedate
timecolumn()
。它也不使用颜色调色板,而是简单地通过十六进制代码和
lc rgb var
定义颜色(检查
help colorspec

  • 定义一个数组

    L[8]
    ,它将存储您想要的值,即
    L[8] = [xfirst, xmin, xmax, xlast, yfirst, ymin, ymax, ylast]

  • 定义一个函数

    getLabels()
    ,它提取所有上述值,但在绘图期间仅返回当前日期
    t
    。检查
    help timecolumn
    help operators binary
    (连续评估)和
    help ternary

  • 数组

    L
    将使用绘图样式
    with labels
    进行绘制,但仅显示前 4 个值 (
    every :::3
    ),请选中
    help every
    。 y 值取自
    L[5:8]

正如您所指出的,默认情况下标签将以点为中心绘制。那么,如何进行适当的转移呢?据我所知,没有可变文本偏移量。好吧,您可以向 x 和 y 值添加一些偏移量,但这将取决于轴的范围。您需要一些字符偏移。

一种可能的方法:

  • 首先将所有标签在 y 方向上以字符为单位向上移动 1,即
    offset 0,1
  • 然后定义一个函数(使用
    sprintf()
    和三元运算符),根据需要移动标签:
    first
    向左,
    min
    向下,
    max
    保持原位,
    last
    向右。
  • 左和右是通过在前面或后面添加增强文本
    &{mmmm}
    (选中
    help enhanced
    )来完成的。您也可以只使用空格
           
    ,但使用比例字体时,您将需要相当多的空格。
  • 由于所有标签在 y 方向上偏移 1,因此您需要再次向下移动所有标签(
    max
    除外),只需在标签前面添加
    "\n"
    即可。
    min
    需要额外的
    "\n"

我希望这些解释足以理解下面的脚本。

数据:

SO77892737.dat

2020-01-01,74.06,73.19,81.96,77.38
2020-02-01,76.08,64.09,81.81,68.34
2020-03-01,70.57,53.15,76.0,63.57
2020-04-01,61.63,59.23,73.63,73.45
2020-05-01,71.56,71.46,81.06,79.49
2020-06-01,79.44,79.3,93.1,91.2
2020-07-01,91.28,89.15,106.42,106.26
2020-08-01,108.2,107.89,131.0,129.04
2020-09-01,132.76,103.1,137.98,115.81
2020-10-01,117.64,107.72,125.39,108.86
2020-11-01,109.11,107.32,121.99,119.05
2020-12-01,121.01,120.01,138.79,132.69
2021-01-01,133.52,126.38,145.09,131.96
2021-02-01,133.75,118.39,137.88,121.26
2021-03-01,123.75,116.21,128.72,122.15
2021-04-01,123.66,122.49,137.07,131.46
2021-05-01,132.04,122.25,134.07,124.61
2021-06-01,125.08,123.13,137.41,136.96
2021-07-01,136.6,135.76,150.0,145.86
2021-08-01,146.36,144.5,153.49,151.83
2021-09-01,152.83,141.27,157.26,141.5
2021-10-01,141.9,138.27,153.17,149.8
2021-11-01,148.99,147.48,165.7,165.3
2021-12-01,167.48,157.8,182.13,177.57
2022-01-01,177.83,154.7,182.94,174.78
2022-02-01,174.01,152.0,176.65,165.12
2022-03-01,164.7,150.1,179.61,174.61
2022-04-01,174.03,155.38,178.49,157.65
2022-05-01,156.71,132.61,166.48,148.84
2022-06-01,149.9,129.04,151.74,136.72
2022-07-01,136.04,135.66,163.63,162.51
2022-08-01,161.01,157.14,176.15,157.22
2022-09-01,156.64,138.0,164.26,138.2
2022-10-01,138.21,134.37,157.5,153.34
2022-11-01,155.08,134.38,155.45,148.03
2022-12-01,148.21,125.87,150.92,129.93
2023-01-01,130.28,124.17,147.23,144.29
2023-02-01,143.97,141.32,157.38,147.41
2023-03-01,146.83,143.9,165.0,164.9
2023-04-01,164.27,159.78,169.85,169.68
2023-05-01,169.28,164.31,179.35,177.25
2023-06-01,177.7,176.93,194.48,193.97
2023-07-01,193.78,186.6,198.23,196.45
2023-08-01,196.24,171.96,201.73,187.87
2023-09-01,189.49,167.62,189.98,171.21
2023-10-01,171.22,165.67,182.34,170.77
2023-11-01,171.0,170.12,192.93,189.95
2023-12-01,190.33,187.45,196.62,192.53

脚本:

### add labels depending on data
reset session

FILE = "SO77892737.dat"

set datafile separator ","
set style fill solid noborder
set key noautotitle
set format x "%Y\n%b" time
myFmt = "%Y-%m-%d"
set offsets graph 0.1, graph 0.1, graph 0.21, graph 0.1

array L[8]   # array to store the label values

getLabels(col) = (t=timecolumn(col,myFmt), $0==0 ? \
            (L[1]=L[2]=L[3]=L[4]=t, L[5]=$2, L[6]=$3, L[7]=$4, L[8]=$5) : \
            (L[4]=t,L[8]=$5),$3<L[6] ? (L[2]=t,L[6]=$3): 0, $4>L[7] ? (L[3]=t,L[7]=$4): 0, t)

Label(i) = sprintf("%s%s%g%s",i!=3?"\n":"", i==4?"&{mmmmm}":i==2?"\n":"", \
                   L[i+4],i==1?"&{mmmmm}\n":i==3?"\n\n":"")

plot FILE u (getLabels(1)):2:3:4:5:($5 < $2 ? 0xff0000 : 0x00ff00) w candle lc rgb var, \
     L every ::::3 u (L[$0+1]):(L[$0+5]):(Label($0+1)) w labels offset 0,1
### end of script

结果:

数组

L
实际上保存的是值:

[1577836800.0,1583020800.0,1690848000.0,1701388800.0,74.06,53.15,201.73,192.53]

© www.soinside.com 2019 - 2024. All rights reserved.