如何使用gnuplot绘制三元相图?
用gnuplot绘制三元相图的实现方法
gnuplot本身没有内置三元相图支持,核心解决思路是利用三元坐标的归一化特性,将三元坐标手动转换为二维笛卡尔坐标后再绘图,具体操作如下:
具体操作步骤
- 前置归一化处理
三元相图的三个组分总和固定为1或100%,先确保你的原始数据中三个组分的数值满足该规则,若为百分比数据需先除以100做归一化。 - 定义坐标转换函数
直接在gnuplot中定义等边三元坐标到二维坐标的转换规则,同时设置画布比例避免三角形变形,相关命令如下:# 保证等边三角形比例不失真 set size ratio -1 # 设置二维坐标范围,匹配等边三角形的尺寸 set xrange [0:1] set yrange [0:sqrt(3)/2] # 定义三元坐标(a,b,c)转二维(x,y)的函数,a+b+c=1 tri_x(a,b,c) = b + c/2 tri_y(a,b,c) = c * sqrt(3)/2 # 隐藏原生xy轴的边框和刻度,后续手动绘制三元轴 unset border unset xtics unset ytics - 手动绘制三元相图的边框、网格
按照等边三角形的坐标绘制三个边框,按需添加辅助网格,示例命令如下:# 绘制三元相图外边框 set arrow from 0,0 to 1,0 nohead lc "black" lw 2 set arrow from 1,0 to 0.5,sqrt(3)/2 nohead lc "black" lw 2 set arrow from 0.5,sqrt(3)/2 to 0,0 nohead lc "black" lw 2 # 绘制间隔10%的平行网格 do for [i=1:9] { # 平行于左腰的网格 set arrow from i/10.0, 0 to i/20.0, (i/10.0)*sqrt(3)/2 nohead lc "gray" dashtype 2 # 平行于右腰的网格 set arrow from 1 - i/10.0, 0 to 1 - i/20.0, (i/10.0)*sqrt(3)/2 nohead lc "gray" dashtype 2 # 平行于底边的网格 set arrow from 0, i*sqrt(3)/20 to 1 - i/10.0, i*sqrt(3)/20 nohead lc "gray" dashtype 2 } - 添加轴标签与刻度
手动在对应坐标位置添加三个组分的标签和刻度,示例如下:# 三个顶点的组分标签,可自行替换为你的组分名称 set label "纯组分A" at -0.05, -0.05 set label "纯组分B" at 1.05, -0.05 set label "纯组分C" at 0.5, sqrt(3)/2 + 0.05 # 按10%间隔添加底边刻度标签,其余轴的刻度按相同逻辑调整位置即可 do for [i=1:9] { set label sprintf("%d%%", i*10) at i/10.0, -0.03 center } - 绘制实际数据
直接调用提前定义的转换函数读取你的数据文件绘图即可,示例命令如下(假设你的数据文件有三列,依次为a、b、c的数值):# 绘制散点数据 plot "你的数据文件路径" u (tri_x($1,$2,$3)):(tri_y($1,$2,$3)) w p pt 7 lc "red" title "实验数据" # 如需绘制相边界、等温线等线性元素,将对应边界点的三元数据按相同方式转换后绘图即可
注意事项
- 如需绘制带填充的相区,可使用
with filledcurves参数,按顺序传入相区边界的转换后坐标即可实现填充效果 - 也可直接使用社区公开的gnuplot三元相图模板,替换对应参数和数据即可快速出图,无需从零编写转换逻辑
内容的提问来源于stack exchange,提问作者Ottmar Schaub
相关产品推荐
相关产品推荐

