如何制作一个非线性颜色条?

编程语言 2026-07-10

我手头有一个数据文件,其中有大量落在 [-5:5] 区间内的数据,还有一些极端数据,数值大约在 -20左右。若使用线性颜色刻度,较小幅值的数据在图上看不清。因此我尝试使用基于tanh() 函数的非线性色标来放大较小的数值,同时在不让颜色刻度饱和的前提下可视化较大的数值。下面是我的脚本和结果。

#!/usr/bin/env gnuplot

# width and height in inches; pixes per inch
w = 12.0 
h = 8.0 
ppi = 150 
set term pngcairo enh col size (w*ppi),(h*ppi) font ",18" 
set output 'mwe.png'

# nonlinear cb scale functions, z in [-zmax,zmax] 
beta = 3.0 
scale(z,zmax) = tanh(beta * (z/zmax)) 
invscale(z,zmax) = zmax * (atanh(z) / beta)

set pm3d map interp 0,0 
set palette maxcol 0 
set xrange [-90:90] 
set yrange [80:200] 
set xtics -90,45,90

set nonlinear cb via scale(z,20) inverse invscale(z,20) 
set cbrange [-20:20] 
set cbtics -20,10,20

splot 'data.txt' us 1:2:7

在此输入图片描述

数据文件在此处

我想要改变的是,不是让颜色箱中的刻度标记呈现非线性,而是让刻度线呈线性,同时使用非线性颜色标尺。因此颜色本身应该被拉伸,而不是刻度标记。可以这样实现吗?

解决方案

使用 "set palette" 命令根据RGB分量(如果更方便,也可以使用CMY或 HSV)定义一个非线性调色板。

从文档中可以看到:

``` gnuplot> help set palette functions

  set palette functions <f1(gray)>, <f2(gray)>, <f3(gray)>

This option is like set palette rgbformulae except that you must provide an actual function for each color component rather than the index of a preset function. The dummy parameter of each function, if any, must be "gray". The function must map gray values in [0,1] to output values also in [0,1].

Examples:

To produce a full color palette use: set palette model HSV functions gray, 1, 1

A nice black to gold palette: set palette model RGB functions 1.1gray0.25, gray*0.75, 0

A gamma-corrected black and white palette gamma = 2.2 map(gray) = gray**(1./gamma) set palette model RGB functions map(gray), map(gray), map(gray) ```

备选方案

正如Ethan的回答所指出的,你需要为r(gray), g(gray), b(gray) 找到合适的函数。参数 gray 的取值范围是 [0:1],这些函数也应在RGB的取值范围 [0:1] 内生成结果。 因此,我不认为 tanh() 是一个合适的函数,因为它将区间 [-infinity:+infinity] 映射到区间 [-1:1],然而你只想显示zrange为 [zmin:zmax]

你可以通过 test palette 在gnuplot控制台中可视化一个调色板。

因此,你需要找到在将 gray 从0 增加到1 时,能够得到从白色到蓝色再到红色的蓝色到红色渐变的函数。下面给出一些具体的函数示例。在最后两个示例中,你可以通过参数 beta 调整“线性”范围以及曲线向饱和蓝色和红色方向的陡度。

脚本:

### Test different palettes
reset session

f(c) = 1 - (2*abs(c-0.5))**beta

r(c) = c<0.5 ? f(c) : 1    # red
g(c) = f(c)                # green
b(c) = c<0.5 ? 1 : f(c)    # blue
set palette functions r(gray), g(gray), b(gray)

# linear
beta = 1
test palette
pause -1

# quadratic
beta = 2
test palette
pause -1

# root A
beta = 0.5
test palette
pause -1

# root mirrored
beta = 0.3
f(c) =  ((1 - sgn(c-0.5))*c**beta + (1 + sgn(c-0.5))*(1-c)**beta)*0.5**(1-beta)
test palette
pause -1
### end of script

结果:

在此输入图片描述

在此输入图片描述

在此输入图片描述

在此输入图片描述

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章