如何在rrdtool中实现左右Y轴刻度独立变化?
RRDtool 实现左右Y轴刻度动态独立调整的方法
方案1:分两次执行Graph命令,先获取数据极值再计算轴参数
RRDtool的--right-axis不支持直接引用CDEF,但可以通过两次调用Graph命令实现动态刻度:
- 提取右侧数据的极值:用
PRINT指令输出右侧CDEF处理后数据的最大/最小值,将结果保存为变量# 输出最大值和最小值到临时变量 read max_val min_val < <(rrdtool graph /dev/null \ DEF:r_data=your.rrd:target_ds:AVERAGE \ CDEF:processed_r=r_data,YOUR_CDEF_EXPR \ PRINT:processed_r:MAX:%lf \ PRINT:processed_r:MIN:%lf) - 计算右轴比例与偏移:基于左轴的预期范围(或同样提取左轴极值),计算
--right-axis需要的比例和偏移值。例如,若左轴范围是0到left_max,右轴范围是min_val到max_val,则:left_max=$(rrdtool graph /dev/null DEF:l_data=your.rrd:left_ds:AVERAGE PRINT:l_data:MAX:%lf | tail -n1) ratio=$(echo "scale=4; $left_max / ($max_val - $min_val)" | bc) offset=$(echo "scale=4; -($min_val * $ratio)" | bc) - 生成最终图表:将计算出的
ratio和offset传入--right-axis参数rrdtool graph final.png \ DEF:l_data=your.rrd:left_ds:AVERAGE \ DEF:r_data=your.rrd:target_ds:AVERAGE \ CDEF:processed_r=r_data,YOUR_CDEF_EXPR \ LINE1:l_data#0000FF:"Left Series" \ LINE1:processed_r#FF0000:"Right Series" \ --right-axis $ratio:$offset
方案2:缩放数据+自定义轴标签,模拟动态右轴
如果不需要严格的刻度对齐,可通过CDEF将右侧数据缩放到左轴显示范围,再用--right-axis-format显示原始数值,视觉上实现动态刻度:
rrdtool graph graph.png \ DEF:l_data=your.rrd:left_ds:AVERAGE \ DEF:r_data=your.rrd:right_ds:AVERAGE \ # 将右轴数据缩放到左轴的大致范围(示例:除以10适配左轴0-100的范围) CDEF:scaled_r=r_data,10,/ \ LINE1:l_data#0000FF:"Left Axis" \ LINE1:scaled_r#FF0000:"Right Axis" \ --right-axis 1:0 \ # 让右轴标签显示原始未缩放的数值 --right-axis-format "%.0lf"
方案3:用脚本封装实现自动化
用Perl、Python等脚本语言封装RRDtool调用,先通过rrdtool fetch获取原始数据,在脚本内计算极值和轴参数,再自动生成并执行Graph命令。例如Python示例(需安装rrdtool模块):
import rrdtool # 获取右侧数据 data = rrdtool.fetch('your.rrd', 'AVERAGE', '--start', '-1d') r_values = [v[0] for v in data[2] if v[0] is not None] processed_r = [v * 10 for v in r_values] # 替换为你的CDEF逻辑 max_val = max(processed_r) min_val = min(processed_r) # 获取左轴最大值 l_data = rrdtool.fetch('your.rrd', 'AVERAGE', '--start', '-1d') l_values = [v[1] for v in l_data[2] if v[1] is not None] left_max = max(l_values) # 计算轴参数 ratio = left_max / (max_val - min_val) if (max_val - min_val) !=0 else 1 offset = -min_val * ratio # 生成图表 rrdtool.graph('final.png', f'--right-axis={ratio}:{offset}', 'DEF:l_data=your.rrd:left_ds:AVERAGE', 'DEF:r_data=your.rrd:right_ds:AVERAGE', 'CDEF:processed_r=r_data,10,*', 'LINE1:l_data#0000FF:"Left Series"', 'LINE1:processed_r#FF0000:"Right Series"' )
内容的提问来源于stack exchange,提问作者Chris Hecker
相关产品推荐
相关产品推荐

