英文:
How to get the relationship between X and Y ranges in gnuplot
问题
我正在使用圆形绘制数据,如下所示:
$DATA<<EOD
1.0000,"CAN",80.6600,1.6700,0.2879,
2.0000,"DEU",79.8400,1.3600,0.4134,
3.0000,"DNK",78.6000,1.8400,0.2144,
4.0000,"EGY",72.7300,2.7800,0.4077,
5.0000,"GBR",80.0500,2.0000,0.3610,
6.0000,"IRN",72.4900,1.7000,0.3906,
7.0000,"IRQ",68.0900,4.7700,0.2810,
8.0000,"ISR",81.5500,2.9600,0.2195,
9.0000,"RUS",68.6000,1.5400,0.5696,
10.0000,"USA",78.0000,2.0000,1.0000,
EOD
set datafile separator comma
set style data circles
set term windows
unset xtics; unset ytics; unset x2tics; unset y2tics
set grid xtics layerdefault
set grid ytics layerdefault
set xtics nomirror
set ytics nomirror
set border 3.00000
set colorsequence classic
set title "This is My Title"
set xlabel "Cities"
set ylabel "Population (in Millions)"
set key default
set style fill solid 4.00 transparent
plot $DATA every ::0::0 using ($3):($4):($5) title "CAN",\
$DATA every ::1::1 using ($3):($4):($5) title "DEU",\
$DATA every ::2::2 using ($3):($4):($5) title "DNK",\
$DATA every ::3::3 using ($3):($4):($5) title "EGY",\
$DATA every ::4::4 using ($3):($4):($5) title "GBR",\
$DATA every ::5::5 using ($3):($4):($5) title "IRN",\
$DATA every ::6::6 using ($3):($4):($5) title "IRQ",\
$DATA every ::7::7 using ($3):($4):($5) title "ISR",\
$DATA every ::8::8 using ($3):($4):($5) title "RUS",\
$DATA every ::9::9 using ($3):($4):($5) title "USA",\
$DATA every ::9::9 using ($3):($4)+($5):($2) with labels center notitle,\
$DATA every ::9::9 using ($3)-($5):($4):($2) with labels center notitle,\
$DATA every ::9::9 using ($3):($4)-($5)/2+0.1:($2) with labels center notitle
使用我的最后三行,我试图将标签放在圆上方、左侧和下方。
将标签放在圆的左侧(或右侧)不是问题,因为圆的半径与x轴的比例相匹配。这没问题。
将标签放在圆的顶部不起作用,因为y轴的比例与x轴不同。
将标签放在圆的底部是可以的,但需要一些计算,通过除以2并添加0.1的附加逻辑适用于USA条目,但对于较小的数据点失败。
我的问题是:是否有一种方法可以获取X和Y平面之间的关系/比例,以便我可以计算顶部/底部标签的偏移量?(除了发出show x/yrange命令并读取输出之外)
我尝试了"set view equal xy"命令,但没有改变任何东西,而"show size"命令显示当前比例为1,1。
谢谢
Roberto
英文:
I am plotting data using circles like this:
$DATA<<EOD
1.0000,"CAN",80.6600,1.6700,0.2879,
2.0000,"DEU",79.8400,1.3600,0.4134,
3.0000,"DNK",78.6000,1.8400,0.2144,
4.0000,"EGY",72.7300,2.7800,0.4077,
5.0000,"GBR",80.0500,2.0000,0.3610,
6.0000,"IRN",72.4900,1.7000,0.3906,
7.0000,"IRQ",68.0900,4.7700,0.2810,
8.0000,"ISR",81.5500,2.9600,0.2195,
9.0000,"RUS",68.6000,1.5400,0.5696,
10.0000,"USA",78.0000,2.0000,1.0000,
EOD
set datafile separator comma
set style data circles
set term windows
unset xtics; unset ytics; unset x2tics; unset y2tics
set grid xtics layerdefault
set grid ytics layerdefault
set xtics nomirror
set ytics nomirror
set border 3.00000
set colorsequence classic
set title "This is My Title"
set xlabel "Cities"
set ylabel "Population (in Millions)"
set key default
set style fill solid 4.00 transparent
plot $DATA every ::0::0 using ($3):($4):($5) title "CAN",\
$DATA every ::1::1 using ($3):($4):($5) title "DEU",\
$DATA every ::2::2 using ($3):($4):($5) title "DNK",\
$DATA every ::3::3 using ($3):($4):($5) title "EGY",\
$DATA every ::4::4 using ($3):($4):($5) title "GBR",\
$DATA every ::5::5 using ($3):($4):($5) title "IRN",\
$DATA every ::6::6 using ($3):($4):($5) title "IRQ",\
$DATA every ::7::7 using ($3):($4):($5) title "ISR",\
$DATA every ::8::8 using ($3):($4):($5) title "RUS",\
$DATA every ::9::9 using ($3):($4):($5) title "USA",\
$DATA every ::9::9 using ($3):($4)+($5):($2) with labels center notitle,\
$DATA every ::9::9 using ($3)-($5):($4):($2) with labels center notitle,\
$DATA every ::9::9 using ($3):($4)-($5)/2+0.1:($2) with labels center notitle
With my last three lines I am trying to position a label above, left and below the circle.
Positioning the label on the left (or right) of the circle is not a problem since the radius of the circle matches the scale for the x plane. This is ok.
Positioning the label at top of the circle does not work the same because the y scale is not the same as the x plane.
Positioning the label at bottom of the circle can be done but it requires some calculation, the added logic to divide by 2 and add 0.1 works for the USA entry but it fails for smaller data points.
My question is: Is there a way to get the relationship\scale between the X and Y planes so I can calculate the offset for the Top\Bottom labels? (Besides issuing a show x\yrange commands and reading back the output)
I tried the "set view equal xy" command but it changed nothing, and the "show size" command shows 1,1 for the current scale.
Thank you
Roberto
答案1
得分: 2
你可以访问名为 GPVAL_X_MIN
和其他变量的变量。所以你可以使用:
charsize=1.5
LEN=3
ratio=1
plot '012_d.dat' every ::9::9 using 3:4:5 w circles title "USA",\
'' every ::9::9 using 3:($4+ratio*$5):2 with labels center offset 0,charsize notitle,\
'' every ::9::9 using ($3-$5):4:2 with labels center offset -LEN,0 notitle,\
'' every ::9::9 using 3:($4-ratio*$5):2 with labels center offset 0,-charsize notitle
ratio=(GPVAL_Y_MAX-GPVAL_Y_MIN)/(GPVAL_X_MAX-GPVAL_X_MIN)
replot
解决方案的关键点(以及向后)是,在绘图后 GPVAL_X_MIN
(和其他变量)才有正确的值,因此你必须使用 replot
。
注意事项
-
如果你不需要转换列的值,你不必使用 "$" 符号,例如
using ($3):($4):($5)
等同于using 3:4:5
-
如果在
plot
命令中再次使用数据(文件),你不必再次写入文件名:''
。
编辑
-
正如你所说,你可以(必须)微调解决方案:在
using 3:($4+ratio*$5):2
中,你可以使用一个常数乘数;并且你可以改变(减小) charsize。在这种情况下,标签的偏移将更依赖于数据。 -
正如 @theozh 所说,你可以使用一个循环来压缩你的代码。然而,这比我最初想象的更复杂:
首先,你必须使用类似以下的东西:
plot for[i=0:9] '012_d.dat' every ::i::i using 3:4:5 title $2
然而,这并没有起到任何关键作用。我的第二个想法是:
plot for[i=0:9] '012_d.dat' every ::i::i using 3:4:5 title sprintf("%s",$2)
f_sprintf: attempt to print numeric value with string format
正如你所看到的,这并没有更好。在搜索 help plot title
后,我找到了解决办法:
语法:
title <文本> | notitle [<被忽略的文本>]
title columnheader | title columnheader(N)
{at {beginning|end}} {{no}enhanced}其中 <文本> 是带引号的字符串或一个评估为字符串的表达式。引号不会显示在图例中。注意:从 gnuplot 版本 5.4 开始,如果 <文本> 是一个表达式或函数,它将在相应的函数或数据流绘制后进行评估。这允许标题引用在绘图期间计算或输入的数量,这在较早的 gnuplot 版本中是不可能的。
我找到了在 using
部分的一个虚假赋值:
plot for[i=0:9] '012_d.dat' every ::i::i using ((x=stringcolumn(2)) eq "XXX"?1/0:$3):4:5 title sprintf("%s",x)
这个方法有效 其他部分的 plot
如下:
plot for[i=0:9] '012_d.dat' every ::i::i using ((x=stringcolumn(2)) eq "XXX"?1/0:$3):4:5 title sprintf("%s",x),\
for[i=0:9] '' every ::i::i using 3:($4+ratio*$5):2 with labels center offset 0,charsize notitle,\
for[i=0:9] '' every ::i::i using ($3-$5):4:2 with labels center offset -LEN,0 notitle,\
for[i=0:9] '' every ::i::i using 3:($4-ratio*$5):2 with labels center offset 0,-charsize notitle
英文:
You can access variables named GPVAL_X_MIN
and others. So you can use:
charsize=1.5
LEN=3
ratio=1
plot '012_d.dat' every ::9::9 using 3:4:5 w circles title "USA",\
'' every ::9::9 using 3:($4+ratio*$5):2 with labels center offset 0,charsize notitle,\
'' every ::9::9 using ($3-$5):4:2 with labels center offset -LEN,0 notitle,\
'' every ::9::9 using 3:($4-ratio*$5):2 with labels center offset 0,-charsize notitle
ratio=(GPVAL_Y_MAX-GPVAL_Y_MIN)/(GPVAL_X_MAX-GPVAL_X_MIN)
replot
The key point (and backward) of the solution is that GPVAL_X_MIN
(and others) has a correct value after a plot, therefore you have to use replot
.
NOTES
-
If you don't transform the value of a column, you don't have to use "$" eg.
using ($3):($4):($5)
is equal tousing 3:4:5
-
If you use the data(file) again in a
plot
command, you don't have to write the (file)name again:''
.
EDIT
-
As you said, you can (have to) fine tuning the solution: in the
using 3:($4+ratio*$5):2
you can use a constant multiplier; and you can change (decrease) the charsize. In this case, the offset of the labels will be more dependent on the data. -
As @theozh said, you can use a loop, to compress your code. However, it is more tricky as I thought at first:
At first think, you have to use something like:
plot for[i=0:9] '012_d.dat' every ::i::i using 3:4:5 title $2
However, this do not make any key. My second though was:
plot for[i=0:9] '012_d.dat' every ::i::i using 3:4:5 title sprintf("%s",$2)
f_sprintf: attempt to print numeric value with string format
As you can see, that isn't better. After a search for help plot title
> Syntax:
> title < text> | notitle [< ignored text>]
> title columnheader | title columnheader(N)
> {at {beginning|end}} {{no}enhanced}
>
> where < text> is a quoted string or an expression that evaluates to a
> string. The quotes will not be shown in the key. Note: Starting with
> gnuplot version 5.4, if < text> is an expression or function it it
> evaluated after the corresponding function or data stream is plotted.
> This allows the title to reference quantities calculated or input
> during plotting, which was not possible in earlier gnuplot versions.
I have figured out a fake assignment in the using
part:
plot for[i=0:9] '012_d.dat' every ::i::i using ((x=stringcolumn(2)) eq "XXX"?1/0:$3):4:5 title sprintf("%s",x)
which has worked With the other parts of the plot
:
plot for[i=0:9] '012_d.dat' every ::i::i using ((x=stringcolumn(2)) eq "XXX"?1/0:$3):4:5 title sprintf("%s",x),\
for[i=0:9] '' every ::i::i using 3:($4+ratio*$5):2 with labels center offset 0,charsize notitle,\
for[i=0:9] '' every ::i::i using ($3-$5):4:2 with labels center offset -LEN,0 notitle,\
for[i=0:9] '' every ::i::i using 3:($4-ratio*$5):2 with labels center offset 0,-charsize notitle
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论