Gnuplot 4d根据数据以不同的透明度绘制颜色条
问题描述:
我想绘制使用splot(x y z值)的4d绘图。我想有第四栏显示为热色。到目前为止,我很好。在网上搜索答案之后,我无法弄清楚的是,点的颜色是透明的,但根据其价值有不同的透明度。Gnuplot 4d根据数据以不同的透明度绘制颜色条
例如,假设我有以下数据集:
0 0 0 0.1
0 0 1 0.2
0 1 0 0.2
0 1 1 2
1 0 0 1
1 0 1 3
1 1 0 0.5
1 1 1 4
现在,我想使颜色条(为第4列)是这样:在接近第4列的值是1,图中的点/点越透明。我看过的所有地方只能给我整个色条的统一透明度。
我想知道有没有人处理过这个,或者有一个想法如何做到这一点。 非常感谢!
答
我并没有完全理解透明度如何取决于值,所以我会给出一个一般答案,您可以在其中替换透明度函数。
虽然您可以指定transparency for line colors,但在使用调色板时这似乎不可行,这将是实现您想要的最直接的方法。只能使用gnuplot的最远距离是让颜色显示为透明,如下面的脚本,其中in.data是包含示例数据的文件。
#!/usr/bin/env gnuplot
set term pngcairo
in_data = "in.data"
set out "out.png"
# function to combine color and alpha channels with white background
# 0: no transparency, 1: fully transparent
make_transparent(x1, t) = (1-t)*x1 + t
# a function to decide transparency
# the input and output must be in range of [0,1]
#get_transparency(x1) = 0 # no transparency
#get_transparency(x1) = 1 # fully transparent
get_transparency(x1) = 1 - x1 # smaller values are more transparent
# convenience function to truncate values
minval(x1, x2) = x1<x2?x1:x2
maxval(x1, x2) = x1>x2?x1:x2
truncval(x1, xmin, xmax) = maxval(minval(x1, xmax), xmin)
trunc(x1) = truncval(x1, 0, 1)
# the default palette consists of rgbfunctions 7,5,15
# we redefine their transparency enabled versions here
# the input and output must be in range of [0,1]
# see other formulae with "show palette rgbformulae" command in gnuplot
f7(x1) = make_transparent(sqrt(x1) , get_transparency(x1))
f5(x1) = make_transparent(x1**3 , get_transparency(x1))
f15(x1) = make_transparent(trunc(sin(2*pi*x1)), get_transparency(x1))
set palette model RGB functions f7(gray),f5(gray),f15(gray)
splot in_data palette
此脚本假定背景为白色,但可以适应任何其他纯色背景。然而,一旦点开始重叠,它就会分崩离析。
为了获得真正的透明度,您需要将每个数据点绘制为单独的线条,并为其赋予不同的线条颜色。这可以通过预处理数据来实现,如下面的bash脚本。
#!/usr/bin/env bash
set -eu
in_data="in.data"
out_png="out.png"
pi=3.141592653589793
# function to convert data value into rgba value
function value2rgba()
{
# arguments to function
local val="${1}"
local min="${2}"
local max="${3}"
# normalized value
local nval=$(bc -l <<< "(${val}-${min})/(${max}-${min})")
#### alpha channel value ####
local alpha="$(bc -l <<< "255 * (1-${nval})")"
# round to decimal
alpha=$(printf "%0.f" "${alpha}")
#### red channel value ####
# rgbformulae 7 in gnuplot
local red="$(bc -l <<< "255 * sqrt(${nval})")"
# round to decimal
red=$(printf "%0.f" "${red}")
#### green channel value ####
# rgbformulae 5 in gnuplot
local red="$(bc -l <<< "255 * sqrt(${nval})")"
local green="$(bc -l <<< "255 * ${nval}^3")"
# round to decimal
green=$(printf "%0.f" "${green}")
#### blue channel value ####
# rgbformulae 15 in gnuplot
local blue="$(bc -l <<< "255 * s(2*${pi}*${nval})")"
# round to decimal
blue=$(printf "%0.f" "${blue}")
# make sure blue is positive
if ((blue < 0))
then
blue=0
fi
### whole rgba value
local rgba="#"
rgba+="$(printf "%02x" "${alpha}")"
rgba+="$(printf "%02x" "${red}")"
rgba+="$(printf "%02x" "${green}")"
rgba+="$(printf "%02x" "${blue}")"
echo "${rgba}"
}
# data without blank lines
data="$(sed -E "/^[[:space:]]*$/d" "${in_data}")"
# number of lines
nline=$(wc -l <<< "${data}")
# get the minimum and maximum value of the 4-th column
min_max=($(awk '{ print $4 }' <<< "${data}" | sort -g | sed -n '1p;$p'))
# array of colors for each point
colors=()
while read -r line
do
colors+=($(value2rgba "${line}" "${min_max[@]}"))
done < <(awk '{ print $4 }' <<< "${data}")
# gather coordinates into one row
coords=($(awk '{ print $1,$2,$3 }' <<< "${data}"))
gnuplot << EOF
set term pngcairo
set out "${out_png}"
\$DATA << EOD
${coords[@]}
EOD
nline=${nline}
colors="${colors[@]}"
unset key
splot for [i=0:nline-1] \$DATA \
u (column(3*i+1)):(column(3*i+2)):(column(3*i+3)) \
pt 1 lc rgb word(colors, i+1)
EOF
这些脚本用gnuplot的5
我觉得你不必GNUPLOT测试,但Matlab或倍频。用这些程序做你想做的事情要容易得多。 –
你想要第四列来确定颜色和透明度吗?当它不在0和1之间时,你想要发生什么? – user8153
@ user8153我想第四列确定颜色和透明度。第四列的值对于我的数据总是正值,可能小于或大于1.如果它大于1,那么如果它们接近1,我仍然希望它们更透明。如果我们绘制第四列以对数刻度表示,并且假设对数刻度在1附近是对称的,这意味着它是从10^-n到10^n,其中n是功率,则颜色条的中间将是1,并且最透明。 – James