LAMMPS fix graphics/labels 详解:在 dump image 输出中叠加图片、动态文本与色标图例

原创2026-10-15 19:56:251,647 阅读
文章标签:科学计算高性能计算科研

LAMMPS fix graphics/labels 详解:在 dump image 输出中叠加图片、动态文本与色标图例

fix graphics/labels 是 LAMMPS GRAPHICS 包提供的一条可视化辅助命令(自 11Feb2026 版本引入),它允许直接在 dump image 渲染出的图像上叠加外部位图图片、动态文本标签和颜色刻度(colormap)图例,从而免去后期二次处理图像的繁琐步骤。本文基于当前仓库的官方文档与源码实现,完整讲解其语法、全部关键字参数、与 dump image 的集成方式,并通过动态 matplotlib 嵌入和仓库真实示例演示如何产出带实时标注的科学可视化图像。

功能概述:给 dump image 输出"加标签"

dump image 是 LAMMPS 生成分子结构渲染图的经典命令,而 fix graphics/labels 的作用,是在 dump image 输出图像上叠加三类"标签"对象:

  • image:把一张外部图片(JPEG / PNG / TGA / PPM 格式)嵌入可视化场景,常用于插入结构示意图、数据图表等;
  • text:把一段文本(支持 LAMMPS 变量展开)渲染成位图后叠加,常用于显示步数、温度、能量等实时信息;
  • colorscale:根据同一个 dump image 实例的颜色映射生成色标图例(colormap legend),便于读者从图像颜色反查数值。

其位置坐标既可以解释为模拟盒子坐标系中的坐标(此时对象有真实的前后景深,原子或其他图形对象可以位于标签前后),也可以解释为图像自身坐标系中的坐标(此时标签永远浮在顶层)。选择哪种解释方式由 dump image 命令中 fix 关键字的 fflag1 标志决定,详见下文"与 dump image 的集成"一节。无论采用哪种坐标系,标签本身始终平行于图像平面。

命令语法总览

fix ID group-ID graphics/labels Nevery mode keyword args ...
  • ID、group-ID 与一般 fix 命令规则一致,其中 group-ID 会被该 fix 忽略;
  • graphics/labels 是该 fix 的样式名;
  • Nevery 表示每隔多少个时间步更新一次图形数据,应与对应的 dump image 命令中的 N 参数保持一致,若两者设置不兼容,LAMMPS 会直接报错终止;
  • mode 及后续关键字可选 image、text、colorscale 三类,同一个 fix 命令中可以出现多个 image / text / colorscale 关键字及其参数,也可用续行符 & 分行书写。

源码实现中,构造函数 FixGraphicsLabels::FixGraphicsLabels(见 fix_graphics_labels.cpp)在解析阶段就强制校验 narg >= 4 且 nevery > 0,随后循环解析所有模式关键字,任何未知关键字都会以 Unknown fix graphics/labels ... keyword 报错;每类对象解析完成后分别存入 pixmaps、texts、scales 三个对象列表,并在 end_of_step() 中统一处理。

image 关键字:嵌入外部图片

*image* filename x y z keyword args

必需参数为图片文件名和图片中心位置 x y z,可选关键字如下:

关键字 取值 说明
scale 数值(默认 1.0) 图片缩放倍数,可写成变量(v_name)
transcolor auto / none / r/g/b 透明色选择:auto 取图片左下角像素颜色作为透明色;none 完全关闭透明处理(默认);r/g/b 给出 0~255 的三个整数指定 RGB 透明色

文档给出的示例:

fix pix all graphics/labels 100 image teapot.png 5.0 -1.0 -2.0 transcolor auto
fix pot all graphics/labels 100 image teapot.ppm 1.0 v_ypos v_zpos scale v_prog transcolor 19/92/192

第二条命令演示了位置 y、z 与缩放 scale 全部由 equal-style 变量 v_ypos、v_zpos、v_prog 驱动(注意变量需以 v_ 前缀传入),实现图片在场景中随运行移动和缩放。

支持的图片格式与读取细节

文件名后缀决定解析器:.jpg/.jpeg 按 JPEG 格式、.png 按 PNG 格式、.tga 按 TGA 格式读取,其余后缀一律按 PPM(NetPBM)格式处理。源码中的 read_image() 函数(见 fix_graphics_labels.cpp)实现如下关键逻辑:

  • JPEG:通过 libjpeg 解压,仅支持 8-bit、3 分量(RGB)图像,逐扫描行读入(jpeg_read_scanlines);
  • PNG:通过 libpng 读取,校验文件签名(png_check_sig),会自动把调色板(palette)、灰度、16-bit、带透明通道等变体统一转换为 8-bit RGB(如 png_set_gray_to_rgb、png_set_strip_16、png_set_strip_alpha);
  • TGA:手工解析 TGA 头(TGAHeader),支持未压缩(类型 2)与 RLE 压缩(类型 10)两种编码,并自动完成 BGR→RGB 通道交换与各种方向标志处理;
  • PPM:读取 P3(ASCII)与 P6(二进制)两种变体,拒绝超大或非法尺寸。

并非所有变体都与 LAMMPS 的读取器兼容:JPEG 读取依赖 LAMMPS_JPEG 宏、PNG 读取依赖 LAMMPS_PNG 宏(即编译时需链接对应图形库),遇到不兼容、无法识别或损坏的文件时 LAMMPS 会报错终止,且读取失败信息会具体说明原因(例如 JPEG image format not supported in this LAMMPS binary)。

动态重读机制:运行中更新图片

图片文件只在 MPI rank 0 上读取并存储(if (comm->me == 0))。每次 end_of_step() 执行时,LAMMPS 都会用 platform::file_write_time() 获取文件时间戳并与上次对比(见 fix_graphics_labels.cpp);一旦检测到文件内容被修改,就会自动重新读取。这使"边运行边改图"成为可能——例如在模拟过程中用 matplotlib 生成新图表,下一帧 dump image 就会自动叠加最新版本。

缩放与透明处理

  • 缩放使用双线性插值算法(bilinear scaling);
  • 透明色像素在渲染时被跳过:auto 直接取位图首像素(左下角)作为透明色,none 把透明色置为非法值 -255.0 以完全禁用,r/g/b 则通过 get_color()(见 fix_graphics_labels.cpp)解析三个通道值并校验 0~255 范围。

text 关键字:叠加动态文本标签

*text* labeltext x y z keyword args

labeltext 是标签文本,若含空白必须加引号;其语法要求与 fix print 一致:支持 equal-style 变量 ${name} 与立即变量 $(expression) 两种写法,变量会在每个 Nevery 时间步被求值并展开。位置 x y z 为中心坐标。

可选关键字:

关键字 取值 说明
fontcolor white(默认)/ black / r/g/b 文字颜色
framecolor silver(默认)/ darkgray / white / black / r/g/b 文字外框颜色
backcolor silver(默认)/ darkgray / white / black / r/g/b 文字背景颜色
transcolor silver(默认)/ darkgray / white / black / none / r/g/b 透明色
size 数值(默认 24,可变量) 字符大小(像素,约值),接受 4~512
horizontal 无参数 创建水平文本(默认)
vertical 无参数 创建垂直文本

文档示例:

fix lbl all graphics/labels 1000 text "LAMMPS graphics demo" 5.0 -1.0 -2.0 backcolor darkgray framecolor black
fix info all graphics/labels 1000 text "Step: $(step)  Angle: ${rot}" 5.0 -1.0 -2.0 size 32

第二条命令把运行步数与角度实时写入标签——$(step) 是立即变量,${rot} 是脚本中预先定义的 equal-style 变量,两者在每个 Nevery 步被 input->substitute() 展开后重新栅格化(见 fix_graphics_labels.cpp)。

颜色语义与透明背景技巧

transcolor 的默认值是 silver,其设计巧妙:如果透明色与字体色、背景色、外框色中的某一项相同,那么这些像素不会被绘制。因此默认设置下,文本会以纯白色渲染、且不带背景和外框。若希望文本有背景框,应把 backcolor/framecolor 设为与 transcolor 不同的颜色。

文档特别提示:渲染透明背景文本时,建议选用与背景相近但略深或略亮的颜色,以减少边缘抗锯齿(anti-aliasing)带来的杂色。源码中也印证了抗锯齿策略:文字先以 2 倍尺寸栅格化再缩放回目标尺寸,size 内部会翻倍(txt.size *= 2.0),超过 128 时先按 128 渲染再由 txt.scale 放大(见 fix_graphics_labels.cpp),因此传入 4~512 的合法范围在内部对应 8~1024。

colorscale 关键字:生成色标图例

*colorscale* dump-ID titletext x y z keyword args

colorscale 会为指定 dump-ID 的 dump image 实例创建颜色映射图例:文本显示在图例中央上方,文本左侧为下限值、右侧为上限值,颜色条由下限到上限线性插值生成。该 fix 直接从对应 dump 实例获取实际数值范围。

必需参数为 dump-ID、图例标题文本(含空白需引号,同样支持变量)与中心位置。可选关键字:

关键字 取值 说明
size 数值(默认 24,可变量) 文字大小(像素,约值),4~512;色条的高宽跟随文字大小
length 数值 色标最小长度(近似值,用于决定文字内边距)
tics 非负整数(默认 0) 色条上绘制的分隔刻度线数量,便于对照数值
map atom(默认)/ grid / bond 选择展示 dump image 的哪一种颜色映射(见 4Jul2026 版本新增说明)
fontcolor / framecolor / backcolor / transcolor 同 text 颜色设置;其中 fontcolor 同时决定色条边框与刻度的颜色
horizontal / vertical 无参数 图例方向,默认水平

文档示例(一个 fix 内叠加两个图例):

fix obj all graphics/labels 200 colorscale viz "Atom Velocity" 20.0 6.5 13.0 size 32 length 1000 &
                                  transcolor none framecolor white backcolor darkgray tics 12
fix bnd all graphics/labels 200 colorscale viz "Bond Strain" 20.0 6.5 -13.0 map bond size 32 length 1000

dump image 实例内部实际包含三套独立的颜色映射:原子(由 dump_modify amap 设置)、网格单元(gmap)、键(bmap)。map atom 选择原子映射(默认),map grid 选择网格单元映射,map bond 选择键映射。如果所选映射在该 dump image 中并未真正用于给任何对象上色,LAMMPS 会打印警告,且图例显示该映射(未使用的)默认范围——这一检查在源码 init() 中通过 dump->colormap_active(scale.mapidx) 完成(见 fix_graphics_labels.cpp)。

动态颜色映射的注意点

文档明确警告(Dynamic color maps 提示框):当使用以 min/max 作为上下界的动态颜色映射时,由于 dump 是在 fix 之后执行的,fix 只能取到上一个 dump 输出步的上下界数值。因此叠加 colorscale 图例时一般建议使用固定范围的映射;制作动画电影时尤其如此——固定范围可以防止色标图例因字符宽度变化而伸缩抖动。源码 init() 中也会对动态映射打印警告:Dump ... uses a dynamic color map. Color scale can only use data from previous dump output。

与 dump image 集成:fix 关键字与坐标系统

fix graphics/labels 专为 dump image 的 fix 关键字设计。dump image 中的 fix 关键字格式为(详见 dump_image.rst):

fix fixID color fflag1 fflag2
  • color 取值 type / element / const,对该 fix 绘制的标签对象没有影响(标签颜色由 fix 自身参数决定),const 时的默认色是白色;
  • fflag1 决定标签位置坐标的解释方式:
    • 0:使用模拟盒子坐标系(x、y、z 为真实空间坐标)。此时标签与原子、其他图形对象存在真实的前后遮挡关系(依据 z 坐标与相机距离),标签始终平行于图像平面;
    • 1:使用图像坐标系。(0,0) 为图像左下角,(<图像宽>, <图像高>) 为右上角,此时 z 坐标被忽略,标签永远浮在一切对象之上。
  • fflag2 对该 fix 无意义,会被忽略。

图像坐标系下若两个标签重叠,先加入图像的标签显示在上方;同一 fix 内部的次序无法改变,但可以通过多个 fix 命令配合——dump image 命令行中 fix 关键字的出现顺序决定了哪个 fix 的标签绘制在顶层。

另外,该 fix 绘制的图像默认完全不透明,可通过 dump_modify ftrans 调整透明度。dump image 的颜色样式设置对 image / text 标签均无效。

变量驱动:让标签随模拟"动"起来

image 的位置(x、y、z)、缩放 scale 与 text / colorscale 的 size 均可以写成 equal-style 变量,传入时以 v_name 形式书写(name 为变量名)。每个 Nevery 时间步,fix 都会对这些变量重新求值。

源码中通过 PARSE_VARIABLE 宏实现解析(见 fix_graphics_labels.cpp):当参数以 v_ 开头时记录变量名(置 varflag),否则解析为数值;init() 阶段用 CHECK_VARIABLE 宏(L776-L786)校验变量存在且为 equal-style;end_of_step() 中调用 input->variable->compute_equal(...) 实时求值(如 L864-L869)。若检测到任何变量参与,fix 会注册对应的 compute 触发步(modify->addstep_compute_all / addstep_compute),保证依赖的 compute 结果在正确的时间步可用。更详细的变量使用讨论可参考 fix graphics/objects。

实战:运行时用 matplotlib 生成动态图像并嵌入

文档提供了一套完整方案:在模拟运行过程中用 matplotlib 绘制实时图表,由 fix python/invoke 周期性调用,再把生成的 PNG 透明化处理后嵌入 dump image 输出。该方案需要以 PYTHON 包编译 LAMMPS,并安装 LAMMPS Python 模块。核心输入脚本如下:

python source here """
import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt
from lammps import lammps
"""

python myplot input 2 SELF 0 format pi here """
def myplot(lmpptr, vflag):
   lmp = lammps(ptr=lmpptr)
   fig, ax = plt.subplots(facecolor=(0.9,0.9,0.9),edgecolor='white')
   ax.set_facecolor((0.9,0.9,0.9))
   ax.set_title('Demo Plot: LAMMPS version ' + str(lmp.version()) ,color='white')
   ax.set_xlabel('Time',color='white')
   ax.set_ylabel('Value',color='white')
   ax.tick_params(colors='white')
   for spine in ax.spines.values():
       spine.set_edgecolor('white')
   ax.plot([1,2,3,4,5,6],[2,3,2.5,3.1,2.8,3.0],color='white', linestyle='--')
   fname = 'myplot.png'
   plt.savefig(fname,dpi=180)
   plt.close()
"""

fix plot all python/invoke 1000 post_force myplot
fix label all graphics/labels 100 image myplot.png 20.0 9.0 10.0 transcolor auto scale 0.5

dump viz all image 100 image-*.png type type size 800 800 view 80 10 box yes 0.02 &
             fsaa yes shiny 0.1 ssao yes 23154 0.8 zoom 1.4 fix label type 0 0
dump_modify viz pad 6 backcolor2 gray backcolor darkgray boxcolor silver

关键设计意图:

  1. matplotlib 使用非交互式 agg 后端,保证无界面环境下也能输出 PNG 文件;
  2. myplot() 函数接收 LAMMPS 对象指针与整数标志两个参数(符合 fix python/invoke 的调用约定),通过 lammps(ptr=lmpptr) 重建对象后查询 LAMMPS 版本号写入标题;
  3. 为了让图像叠加后呈"透明"效果,所有线条与文字设置为白色,背景用很亮的灰色(极小化删除背景像素时的抗锯齿残留);
  4. fix label 使用 transcolor auto 自动以左下角(即背景灰色)作为透明色,配合 scale 0.5 缩放;
  5. 图表仅在每第 10 帧 dump 图像时更新(两个 fix 的 Nevery 分别为 1000 与 100)。

把上述命令加入 melt 示例后,输出效果如下图所示——渲染结果中既包含原子结构,又叠加了实时绘制的数据图(示例输出图):

LAMMPS fix graphics/labels 动态 matplotlib 图像叠加示例

仓库内的真实用法示例

除了文档示例,当前仓库的示例脚本也大量使用了该命令:

  • examples/GRAPHICS/in.peptide-hbonds:在一个 fix 中同时叠加两个动态文本标签(用 $(c_hb1:%02.0f) 格式化氢键数目)和一张 hbond-diagram.png 示意图,随后 dump image 以 fix label const 1 0(fflag1=1 即图像坐标系)引入;
  • examples/GRAPHICS/in.breakable:用 text 关键字在场景中叠加标题文本,展示盒子坐标系(fflag1=0)下的用法。

这些示例与文档配合,可作为快速上手的起点。

构建要求与限制

  • fix graphics/labels 属于 GRAPHICS 包(自 11Feb2026 版本新增,dump image、dump movie 及多个 fix graphics/... 样式被整合进该包),只有在以该包构建 LAMMPS 时才可用,见 Build package;
  • 读取 JPEG / PNG 格式图片需要编译时链接对应图形库:CMake 构建通过 -D WITH_JPEG=value 与 -D WITH_PNG=value 开关控制(默认在找到开发文件时自动开启),找不到时可用 -D JPEG_INCLUDE_DIR、-D JPEG_LIBRARY、-D PNG_INCLUDE_DIR、-D PNG_LIBRARY 手动指定路径,详见 Build_extras.rst 的 GRAPHICS 一节;TGA 与 PPM 格式无需额外依赖;
  • 该 fix 不写入二进制重启文件,fix_modify 的选项对它也都不适用。

默认值汇总

参数 默认值
image transcolor none
text transcolor silver
image scale 1.0
text / colorscale fontcolor white
text / colorscale backcolor silver
text / colorscale framecolor silver
text / colorscale size 24
文本 / 图例方向 horizontal
colorscale tics 0
colorscale map atom

相关命令

与可视化、文本输出相关的配套命令:fix print、dump image、fix graphics/arrows、fix graphics/chunk、fix graphics/isosurface、fix graphics/lines、fix graphics/objects、fix graphics/periodic、fix graphics/replica。

登录后查看全文
lammps