【问题标题】:gnuplot 2D polar plot with heatmap from 3D dataset - possible?带有来自 3D 数据集的热图的 gnuplot 2D 极坐标图 - 可能吗?
【发布时间】:2013-09-13 17:58:58
【问题描述】:

我想使用笛卡尔坐标绘制一个我在 3D 中作为表面绘制的图,并将其作为 POLAR 坐标中的 2D 热图查看。这样做的原因是我正在获取该坐标系中系统的数据。我只找到了一些相关的例子,但在试图让它与我的数据一起工作时遇到了困难。我目前正在使用矩阵格式,如果这有助于图表正常工作,我可以重新格式化数据集。

数据是在扬声器上进行的 SPL 测量值。麦克风位于固定距离(例如固定半径)处,并且在水平方向围绕整个扬声器每隔 10 度进行一次测量。 SPL 测量值是 20Hz 至 20kHz 频率的函数。

我想使用 gnuplot 创建一个 2D 极坐标图。频率将被绘制为半径,扬声器周围的角度将是角度,“高度”将是 SPL 级别。这应该会生成一个表面,但是,我想创建一个热图 pm3d,然后从上方(例如视图 0,0)或作为 2D 图查看它。我还需要添加显示 SPL 间隔的等高线并将其叠加在热图上。

我在这里找到了与笛卡尔坐标类似的东西: http://gnuplot-tricks.blogspot.com/2009/07/maps-contour-plots-with-labels.html 当我尝试将极坐标用于最终 2D 图的这种方法时,我收到一条错误消息,指出极坐标图不支持“带图像”选项。有人可以试试这个或确认一下吗?

我已经能够使用 splot 将我的极坐标数据绘制为 3D 中的热图+等高线,并从正上方查看(设置视图 0.0)。如果我首先将现有的极坐标数据转换为笛卡尔坐标,我可能会得到类似于此网页中显示的内容: how to create a 3d polar graph with gnuplot 我也可以从上方查看,但我想添加极坐标网格并为角度和半径添加标签。我是否必须手动执行此操作,或者我可以使用 multiplot 覆盖 2D 网格和从 0.0 查看的 3D 图?

我不确定如何处理这个问题。任何关于采取什么方向的建议将不胜感激。

-查理

【问题讨论】:

    标签: gnuplot heatmap


    【解决方案1】:

    image 绘图仅适用于均匀分布的矩形网格,就像排列任何位图图像一样。否则,您必须使用 splot 和 pm3d。

    set grid polar 仅适用于 2D,因此您必须使用 multiplot 将热图与极坐标网格重叠。这里有一个很长的例子来向你展示它是如何工作的:

    reset
    set terminal pngcairo size 800,800
    set output '3d-polar.png'
    
    set lmargin at screen 0.05
    set rmargin at screen 0.85
    set bmargin at screen 0.1
    set tmargin at screen 0.9
    
    set pm3d map
    unset key
    
    set multiplot
    
    # plot the heatmap
    set parametric
    set isosamples 500
    
    unset border
    unset xtics
    unset ytics
    
    set angles degree
    r = 6
    set urange[0:r] # radius
    set vrange[0:360] # angle
    set xrange[-r:r]
    set yrange[-r:r]
    set colorbox user origin 0.9,0.1 size 0.03,0.8
    splot u*cos(v), u*sin(v), (cos(v)*besj0(2*u))**2
    
    # now plot the polar grid only
    set style line 11 lc rgb 'white' lw 2
    set grid polar ls 11
    set polar
    set rrange[0:r]
    unset raxis
    set rtics format '' scale 0
    unset parametric
    set for [i=0:330:30] label at first (r+0.35)*cos(i), first (r+0.35)*sin(i)\
    center sprintf('%d', i)
    plot NaN w l
    unset multiplot
    

    结果是:

    现在是关于一些技巧的一些细节:

    • 为了获得正方形大小,您不能使用set size ratio 1,因为 2D 和 3D 绘图的边距不同,即使您指定了一些绝对边距。因此,我设置了一个方形画布大小(终端选项size 800,800),并设置了合适的绝对边距。

    • 你不能unset rtics,因为那样网格就会消失。

    • 必须手动设置网格标签。

    • 颜色框也是手动设置的,否则它会与0 标签重叠。

    • 绘制NaN 只绘制网格

    【讨论】:

    • 我能够在我的构建上运行一切(Win32:版本 4.7 补丁级别 0)除了:带有 sprintf 的行生成一个错误,显示“未定义变量:at”。另外,我需要提供一个数据文件,我对文件格式有些困惑。这应该是 x,y,z 数据点(连续数据)吗?我可以使用矩阵格式吗?
    • 更具体地说,如何获取输入数据文件(频率、角度、声压级)并使用参数模式 u 和 v 将其转换为极坐标形式。我认为这就是 Christoph 对数据使用函数形式的原因。但我需要使用文件中的点,我想了解这应该如何工作。谢谢!
    • 再考虑一下输入数据,似乎参数模式命令与此无关......它们只是用于构建极坐标数据集。我认为我必须使用 x=rcos(theta), y=rsin(theta) 将已经是极坐标形式 (r, theta, z) 的数据转换为笛卡尔形式, z。然后我就可以直接在 splot 命令中使用了。我尝试了使用 1*cos(2):1*sin(2):3 的 'splot 'matrix.dat' 非均匀矩阵和使用 $1*cos($2):$1* 的'splot 'matrix.dat' 非均匀矩阵sin($2):$3' 但这些对我不起作用。
    【解决方案2】:

    我拿了 Christoph 发布的命令文件并玩了一会儿,并设法让它满足我的需要,除了标签,我仍然遇到问题。剧情是这样的:

    为了得到这个结果,我不得不重新计算我的测量数据的坐标,将它们从极坐标系(频率=r,theta=离轴角,z=SPL)更改为笛卡尔坐标系(x ,y,z)。同时我修改了极坐标网格的呈现方式。虽然我想要一个对数极坐标 r 轴,但笛卡尔坐标必须用于 pm3d 数据,所以我在使用 r 数据计算 x,y,z 坐标之前取了 r 数据的对数。另外,我知道极坐标对数 r 轴刻度的最小值为 10,当使用对数刻度极坐标网格时,这似乎设置为等于绘图的中心。为了使网格和表面数据正确排列,我从 r 值中减去 log10(10),然后使用它们来计算用于 pm3d 地图的笛卡尔坐标。所以总的来说,我使用的方程是

    r = log10( frequency ) - 1
    x = r cos( theta )
    y = r sin( theta )
    z = SPL
    

    然后我使用以下命令文件来绘制数据:

    reset 
    set terminal pngcairo size 800,800 
    set output '3d-polar.png'
    set lmargin at screen 0.05
    set rmargin at screen 0.85
    set bmargin at screen 0.1
    set tmargin at screen 0.9
    set pm3d map interpolate 20,20
    unset key
    set multiplot
    
    # plot the heatmap
    
    set cntrparam levels increment 3,-3, -24
    set contour surface
    set palette rgb 33,13,10 #rainbow (blue-green-yellow-red)
    set cbrange [-18:0]
    unset border
    unset xtics
    unset ytics
    set angles degree
    r = 3.31
    set xrange[-r:r]
    set yrange[-r:r]
    set colorbox user origin 0.9,0.1 size 0.03,0.8
    splot 'new_test.dat' using 1:2:3
    
    # now plot the polar grid only
    set style line 11 lc rgb 'black' lw 1 lt 0
    set grid polar ls 11
    set polar
    set logscale r 10
    set rrange[10:20000]
    unset raxis
    set rtics format '' scale 0
    set rtics (10,20,100,200,1000,2000,10000,20000)
    #unset parametric
    #set for [i=0:330:30] label at first (r+0.35)*cos(i), first (r+0.35)*sin(i) \
    #center sprintf('%d', i)
    
    plot NaN w l
    
    unset multiplot
    unset output
    

    用于生成绘图的数据仅跨越 +/- 30 度,因此只有该扇区填充极坐标图。额外的角度数据可用于填充绘图。

    如果我能在标签方面获得一些帮助,我可以称之为“完成”。我仍然需要获得角度工作的标签。关于如何标记极地 r 轴抽动的输入,这也是非常受欢迎的。

    【讨论】:

    • 我还用 4.6.3 和当前 4.7 测试了我的脚本,并且标签工作正常。除了使用set for ...,您还可以尝试使用do for [i=0:330:30]{ set label ... }。同样,您也可以在热图上方标记r 值。
    • 我找出了错误的根源:set label 命令语法似乎需要一个标识符标签来遵循说明符序列中的label。标签必须是正整数。我基于 i,例如set for [i=0:330:30] label i/30+1 at...。我认为我之前收到错误的原因是 gnuplot 试图将 at 解释为标签。这里有更多信息:manpagez.com/info/gnuplot/gnuplot-4.4.3/gnuplot_259.php。
    • 不,<tag> 不是必需的,正如您参考的页面中明确指出的那样:If no <tag> is given, the lowest unused tag value is assigned automatically.。但我不明白,为什么 4.7(哪个日期?)出现错误。
    • 我正在使用 4.7 版补丁级别 0 的 MinGW 构建,上次修改时间为 2012 年 9 月 16 日。我以前遇到过这个问题,我必须明确指定一个标签,否则我得到一个错误,所以这可能是一个错误。
    • 是的,这将是一个错误,但您使用的是一年前的开发分支版本,您应该考虑更新它:)。使用日期为 2013-09-09 的版本,它绝对有效。试用最新的预编译二进制文件,日期为 2013-08-01 gnuplot.info/development/binaries。
    猜你喜欢
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 2013-08-29
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    • 2020-10-07
    相关资源
    最近更新 更多