gnuplot:如何为数字 1-999 获得 %c 零空间?

Posted

技术标签:

【中文标题】gnuplot:如何为数字 1-999 获得 %c 零空间?【英文标题】:gnuplot: How to get %c zero space for numbers 1-999? 【发布时间】:2021-01-23 19:10:43 【问题描述】:

据我了解,数字和单位之间应该有一个空格。

然而,在 gnuplot 中,前缀 %c(参见 help format specifiers)对于 1-999 的数字显然似乎是 ' ' 而不是 ''。 因此,在下面的示例图中,xtic 标签和 ytic 标签都不是正确的。 您有一些带有 空格或 两个 空格的 tic 标签,但并非所有标签都带有 one。这是一个细节,也许有些人甚至不会注意到,但如果可能的话,我更愿意以正确的方式来做。

很久以前我发了一个bug report,但到目前为止没有任何回应。 是否有直接的解决方法?

代码:

### wrong prefix for %c 1-999
reset session

set size ratio -1
set logscale xy

set format x "%.0s%cΩ"    # no  space
set format y "%.0s %cΩ"   # one space
set xrange [1e-3:1e12]
set grid x, y
plot x
### end of code

结果:

加法:

根据@maij 指向源代码的回答,这里有一个 gnuplot 尝试“修复”这个问题,应该很容易转移到 C 中。

代码:

### gnuplot "fix" for prefix for %c 1-999

prefix(power) = "yzafpnum kMGTPEZY"[(power+24)/3+1 : (power+24)/3 + sgn(abs(power))]

do for [power=-24:24:3] 
    print sprintf("% 3g  '%s'", power, prefix(power))

### end of code

结果:

-24  'y'
-21  'z'
-18  'a'
-15  'f'
-12  'p'
 -9  'n'
 -6  'u'
 -3  'm'
  0  ''   # zero length
  3  'k'
  6  'M'
  9  'G'
 12  'T'
 15  'P'
 18  'E'
 21  'Z'
 24  'Y'
 

【问题讨论】:

【参考方案1】:

它看起来像一个错误。

这是我想出的解决方法。这样,数字和单位之间总是有一个空格。

您可以使用set xtics add 告诉 gnuplot 在何处分别设置每个刻度线以及每个标签应该是什么。 gprintf 函数可以使用 gnuplot 说明符格式化数字。

因为我们已经知道每个刻度应该有什么值,所以很容易用循环设置它们。

# Function to choose the right label format.
f(x) = (x < 1000 && x >= 1) ? gprintf("%.0f Ω", x) : gprintf("%.0s %cΩ", x)

# Loop to set each tick mark and label.
do for [i=-2:12:2] 
    set xtics add (f(10**i) 10**i)
    set ytics add (f(10**i) 10**i)


set size ratio -1
set logscale xy
set xrange [1e-3:1e12]
set grid x, y

plot x

【讨论】:

感谢您的建议!是的,这修复了它,尽管如果您在 gnuplot 中有自动缩放和自动标签,手动设置抽动并不好。由于我要求立即解决此问题,因此我将接受此答案。不过,我希望它会按照@maij 的建议在源代码中修复。【参考方案2】:

修复源代码:

目前我只有 Debian Stretch gnuplot 5.0.5 版的源代码,行号等可能已经过时了。

问题出在util.c 中的函数gprintf 第868 行附近:

power = (power + 24) / 3;
snprintf(dest, remaining_space, temp, "yzafpnum kMGTPEZY"[power]);

在这里我们看到以下内容:

yzafpnum kMGTPEZY 中的字母是科学前缀。 从 1 到 999,power = (0 + 24) / 3 = 8yzafpnum kMGTPEZY"[8] 是额外的空间

我不是 C 专家,但作为第一次尝试,我将其更改为

power = (power + 24) / 3;
if (power != 8)  
   snprintf(dest, remaining_space, temp, "yzafpnum kMGTPEZY"[power]);
 else  
   snprintf(dest, remaining_space, "%s", "");

gprintf 函数要求至少打印一个终止空字符,很可能有更简单的解决方案。)

无需重新编译的解决方法:

手动设置tic标签怎么样?但我认为你之前提出过这个想法并且不喜欢它。

【讨论】:

谢谢!现在我明白了。这解释了为什么它是' ' 而不是'',因为函数很简单。我同意,这应该非常很容易解决。我希望这将在“官方”源代码中完成,而不是由每个人单独完成。我根本不知道 C,所以我在我的问题中添加了一个 gnuplot 尝试,尽管它不能解决问题。但我确信这可以很容易地翻译成 C。

以上是关于gnuplot:如何为数字 1-999 获得 %c 零空间?的主要内容,如果未能解决你的问题,请参考以下文章

如何为需要 4 个数字输入的 C 程序编写 Bash 脚本? [复制]

gnuplot:如何在每个像素上无边距绘制一个2D数组元素

使用 gnuplot 绘制获得的权力

如何为自定义 CPU 创建 C 编译器?

如何为 C/C++ 编写二进制算法

如何为多个文本框使用一个绑定来分隔 WPF XAML 中的三位数字?