如何摆脱 gnuplot 中相交曲线的小故障?
How to get rid of small glitches in intersecting curves in gnuplot?
这既是一个问题,也是一封写给 theozh 的感谢信,他帮助我在 gnuplot 中创建了我想要的图形。
我试图从他们分享过几次的剧情中找到最漂亮的图片。
这是我的脚本
reset session
set output 'Wavy_curve.svg'
samps = 2500
set samples samps, samps
set isosamples samps, samps
f(x,y) = sin(1.3*x)*cos(0.9*y)+cos(.8*x)*sin(1.9*y)+cos(y*.2*x)
set table $Data01
splot f(x,y)
unset table
g(x,y) = y
set table $Data02
splot g(x,y)
unset table
h(x,y) = 0.5*x
set table $Data03
splot h(x,y)
unset table
Zmin = -3
Zmax= 3
set xrange[-5:5]
set yrange[-5:5]
set zrange[Zmin:Zmax]
set hidden3d
set angle degree
Frac(z) = (z-Zmin)/(Zmax-Zmin)
# MyPalette01
Red01(z) = 65536 * ( Frac(z) > 0.75 ? 255 : int(255*abs(2*Frac(z)-0.5)))
Green01(z) = int(255*sin(180*Frac(z)))*256
Blue01(z) = int(255*cos(90*Frac(z)))
MyPalette01(z) = Red01(z) + Green01(z) + Blue01(z)
# MyPalette02
Red02(z) = 65536 * int(255*Frac(z))
Green02(z) = 256 * (Frac(z) > 0.333 ? 255 : int(255*Frac(z)*3))
Blue02(z) = (Frac(z) > 0.5 ? 255 : int(255*Frac(z)*2))
MyPalette02(z) = Red02(z) + Green02(z) + Blue02(z)
# MyPalette03
Red03(z) = 65536 * (Frac(z) > 0.5 ? 255 : int(255*Frac(z)*2))
Green03(z) = 256 * (Frac(z) > 0.333 ? 255 : int(255*Frac(z)*3))
Blue03(z) = int(255*Frac(z))
MyPalette03(z) = Red03(z) + Green03(z) + Blue03(z)
set pm3d
set pm3d depthorder
set pm3d lighting primary 0.5 specular 0.2
set pm3d ftriangles
set style fill transparent solid 0.8 noborder
unset colorbox
set view 44,316
splot $Data01 u 1:2:3:(MyPalette01()) w l lc rgb var notitle, \
$Data02 u 1:2:3:(MyPalette02()) w l lc rgb var notitle, \
$Data03 u 1:2:3:(MyPalette03()) w l lc rgb var notitle
### end of code
结果
我那可怜的笔记本电脑花了 16 个小时才渲染出来,但我对结果很满意。看来我有几个小故障。这些半透明图通常会发生这种情况。左下角有一个较暗的圆圈。几乎不明显,只有较暗的背景。我想我需要更多样本,但一段时间后它变得非常慢。我只用了 2500 来获得尖锐的交叉点,1000 对于单个表面就足够了。当我使用 0.2 作为透明度时,我也得到了看起来缺少纹理的东西,通过将其增加到 0.8 解决了这个问题。
我使用了 svg 终端,因为 qt 终端为这些需要增加透明度的图提供了丑陋的线条,但最终仍会出现波纹图案。 wxt 在没有线条的情况下处理得更好,但它没有提供完全的透明度,似乎只能显示一个交叉点。有什么技巧可以降低获得此类结果的计算成本吗?
编辑:根据 Ethan 的回答,我使用 svg 终端仅用了 30 秒就得到了这个结果。新问题是 Inkscape 真的很难打开最终约为 300MB 的文件,以便将其导出为 png,只有 1.4MB。是否有另一个终端可以提供像 svg 这样好的结果,但可以直接输出为 png? svg终端可以直接输出为png吗?我将尝试在不打开 inkscape gui 的情况下从命令行进行文件转换,但鉴于文件较大,它仍然不理想。
我不知道你对你的情节有什么限制或要求,但我怀疑你使它变得比获得顺利结果所必需的要难得多。
这是大致相同情节的流畅版本,在我不是特别强大的桌面上执行时间不到 2 秒。我已将三个不同的调色板范围堆叠到一个调色板中,以便 splot 命令可以直接使用调色板,而不是像您的示例脚本那样将其分成离散样本。
通过直接使用调色板,您还可以选择通过添加 set pm3d interpolation N,N
来增加平滑度,尽管我认为这里不需要它。
如果此方法未能解决某些要求,请随时修改问题。
set term pngcairo size 700,500
set output 'Waves.png'
samps = 250
set samples samps, samps
set isosamples samps, samps
f(x,y) = sin(1.3*x)*cos(0.9*y)+cos(.8*x)*sin(1.9*y)+cos(y*.2*x)
g(x,y) = y
h(x,y) = 0.5*x
Zmin = -3
Zmax= 3
set xrange[-5:5]
set yrange[-5:5]
set zrange[Zmin:Zmax]
set pm3d depthorder
set pm3d lighting primary 0.5 specular 0.2
set style fill transparent solid 0.8 noborder
unset colorbox
unset key
set view 44,316
set palette defined (-3 "0x0000df", 0 "0xddff40", 3 "0xdf0000", \
3 "gray40", 9 "0x8fffff", \
9 "gray40", 15 "0xffff8f")
set cbrange [-3:15]
splot '++' u 1:2:(f(x,y)) with pm3d, \
'++' u 1:2:(g(x,y)):(6+g(x,y)) with pm3d, \
'++' u 1:2:(h(x,y)):(12+h(x,y)) with pm3d
这既是一个问题,也是一封写给 theozh 的感谢信,他帮助我在 gnuplot 中创建了我想要的图形。
我试图从他们分享过几次的剧情中找到最漂亮的图片。
这是我的脚本
reset session
set output 'Wavy_curve.svg'
samps = 2500
set samples samps, samps
set isosamples samps, samps
f(x,y) = sin(1.3*x)*cos(0.9*y)+cos(.8*x)*sin(1.9*y)+cos(y*.2*x)
set table $Data01
splot f(x,y)
unset table
g(x,y) = y
set table $Data02
splot g(x,y)
unset table
h(x,y) = 0.5*x
set table $Data03
splot h(x,y)
unset table
Zmin = -3
Zmax= 3
set xrange[-5:5]
set yrange[-5:5]
set zrange[Zmin:Zmax]
set hidden3d
set angle degree
Frac(z) = (z-Zmin)/(Zmax-Zmin)
# MyPalette01
Red01(z) = 65536 * ( Frac(z) > 0.75 ? 255 : int(255*abs(2*Frac(z)-0.5)))
Green01(z) = int(255*sin(180*Frac(z)))*256
Blue01(z) = int(255*cos(90*Frac(z)))
MyPalette01(z) = Red01(z) + Green01(z) + Blue01(z)
# MyPalette02
Red02(z) = 65536 * int(255*Frac(z))
Green02(z) = 256 * (Frac(z) > 0.333 ? 255 : int(255*Frac(z)*3))
Blue02(z) = (Frac(z) > 0.5 ? 255 : int(255*Frac(z)*2))
MyPalette02(z) = Red02(z) + Green02(z) + Blue02(z)
# MyPalette03
Red03(z) = 65536 * (Frac(z) > 0.5 ? 255 : int(255*Frac(z)*2))
Green03(z) = 256 * (Frac(z) > 0.333 ? 255 : int(255*Frac(z)*3))
Blue03(z) = int(255*Frac(z))
MyPalette03(z) = Red03(z) + Green03(z) + Blue03(z)
set pm3d
set pm3d depthorder
set pm3d lighting primary 0.5 specular 0.2
set pm3d ftriangles
set style fill transparent solid 0.8 noborder
unset colorbox
set view 44,316
splot $Data01 u 1:2:3:(MyPalette01()) w l lc rgb var notitle, \
$Data02 u 1:2:3:(MyPalette02()) w l lc rgb var notitle, \
$Data03 u 1:2:3:(MyPalette03()) w l lc rgb var notitle
### end of code
结果
我那可怜的笔记本电脑花了 16 个小时才渲染出来,但我对结果很满意。看来我有几个小故障。这些半透明图通常会发生这种情况。左下角有一个较暗的圆圈。几乎不明显,只有较暗的背景。我想我需要更多样本,但一段时间后它变得非常慢。我只用了 2500 来获得尖锐的交叉点,1000 对于单个表面就足够了。当我使用 0.2 作为透明度时,我也得到了看起来缺少纹理的东西,通过将其增加到 0.8 解决了这个问题。
我使用了 svg 终端,因为 qt 终端为这些需要增加透明度的图提供了丑陋的线条,但最终仍会出现波纹图案。 wxt 在没有线条的情况下处理得更好,但它没有提供完全的透明度,似乎只能显示一个交叉点。有什么技巧可以降低获得此类结果的计算成本吗?
编辑:根据 Ethan 的回答,我使用 svg 终端仅用了 30 秒就得到了这个结果。新问题是 Inkscape 真的很难打开最终约为 300MB 的文件,以便将其导出为 png,只有 1.4MB。是否有另一个终端可以提供像 svg 这样好的结果,但可以直接输出为 png? svg终端可以直接输出为png吗?我将尝试在不打开 inkscape gui 的情况下从命令行进行文件转换,但鉴于文件较大,它仍然不理想。
我不知道你对你的情节有什么限制或要求,但我怀疑你使它变得比获得顺利结果所必需的要难得多。
这是大致相同情节的流畅版本,在我不是特别强大的桌面上执行时间不到 2 秒。我已将三个不同的调色板范围堆叠到一个调色板中,以便 splot 命令可以直接使用调色板,而不是像您的示例脚本那样将其分成离散样本。
通过直接使用调色板,您还可以选择通过添加 set pm3d interpolation N,N
来增加平滑度,尽管我认为这里不需要它。
如果此方法未能解决某些要求,请随时修改问题。
set term pngcairo size 700,500
set output 'Waves.png'
samps = 250
set samples samps, samps
set isosamples samps, samps
f(x,y) = sin(1.3*x)*cos(0.9*y)+cos(.8*x)*sin(1.9*y)+cos(y*.2*x)
g(x,y) = y
h(x,y) = 0.5*x
Zmin = -3
Zmax= 3
set xrange[-5:5]
set yrange[-5:5]
set zrange[Zmin:Zmax]
set pm3d depthorder
set pm3d lighting primary 0.5 specular 0.2
set style fill transparent solid 0.8 noborder
unset colorbox
unset key
set view 44,316
set palette defined (-3 "0x0000df", 0 "0xddff40", 3 "0xdf0000", \
3 "gray40", 9 "0x8fffff", \
9 "gray40", 15 "0xffff8f")
set cbrange [-3:15]
splot '++' u 1:2:(f(x,y)) with pm3d, \
'++' u 1:2:(g(x,y)):(6+g(x,y)) with pm3d, \
'++' u 1:2:(h(x,y)):(12+h(x,y)) with pm3d