CERN ROOT新手求助:从文本文件绘制6幅分组误差棒图
解决CERN ROOT分组读取数据并绘图的问题
嘿,作为刚接触CERN ROOT的新手,碰到这种分组处理数据并绘图的需求确实需要点清晰的指引,我给你整理了一套实用的代码方案,一步步来解决你的问题~
整体思路
咱们的核心需求是按第3列的不同取值分组,提取每组的第1、4、5列数据绘制带误差棒的图,所以步骤大概是:
- 打开文本文件,逐行读取所有列的数据
- 用一个容器按第3列的数值对x、y、ey数据进行分组存储
- 遍历每个分组,用ROOT的
TGraphErrors绘制独立的图像
完整代码示例
下面是可直接复用的代码,我加了详细注释,你可以根据自己的文件名和需求调整:
#include <TFile.h> #include <TGraphErrors.h> #include <TCanvas.h> #include <fstream> #include <map> #include <vector> #include <string> int main() { // 用map来存储分组数据:键是第3列的取值,值是三维vector分别存x、y、ey std::map<double, std::vector<std::vector<double>>> groupedData; // 替换成你的实际数据文件名 std::ifstream inFile("your_data.txt"); if (!inFile.is_open()) { printf("哎呀,打不开文件!请检查文件名和路径是否正确~\n"); return 1; } // 定义变量接收每一行的9列数据 double col1, col2, col3, col4, col5, col6, col7, col8, col9; // 逐行读取数据 while (inFile >> col1 >> col2 >> col3 >> col4 >> col5 >> col6 >> col7 >> col8 >> col9) { // 将对应列的数据存入对应分组 groupedData[col3][0].push_back(col1); // 第1列 → x groupedData[col3][1].push_back(col4); // 第4列 → y groupedData[col3][2].push_back(col5); // 第5列 → ey } inFile.close(); // 遍历每个分组,绘制独立图像 int canvasIndex = 0; for (auto& group : groupedData) { double groupKey = group.first; auto& data = group.second; // 跳过空分组(防止出错) int pointNum = data[0].size(); if (pointNum == 0) continue; // 创建带误差棒的图:参数依次是点数、x数组、y数组、x误差、y误差 TGraphErrors* graph = new TGraphErrors(pointNum, &data[0][0], &data[1][0], nullptr, &data[2][0]); // x误差设为nullptr,需要的话可以补充 // 设置图的标题和样式 graph->SetTitle(Form("Group: %.1f; X Variable; Y Variable", groupKey)); graph->SetMarkerStyle(20); // 用圆形标记点 graph->SetMarkerColor(kBlue); graph->SetLineColor(kRed); graph->SetLineWidth(2); // 创建独立画布 canvasIndex++; TCanvas* canvas = new TCanvas(Form("canvas_%d", canvasIndex), Form("Group %.1f", groupKey), 800, 600); graph->Draw("AP"); // A=显示坐标轴,P=绘制标记点,加"L"可以连线条 // 可选:将画布保存为图片文件 canvas->SaveAs(Form("group_%.1f.png", groupKey)); } return 0; }
关键细节说明
- 分组存储:用
std::map<double, ...>可以自动按第3列的数值对数据进行分组,不用手动判断每个取值,非常省心;如果第3列是字符串,把键改成std::string就行 - 绘图对象:
TGraphErrors是ROOT专门用来绘制带y误差棒的图的类,完美匹配你的需求 - 编译运行:确保ROOT环境已经配置好,编译命令可以用:
然后运行生成的可执行文件即可g++ -o plot_grouped_data plot_grouped_data.cpp `root-config --cflags --libs`
小提示
- 如果想把所有分组的图画在同一张画布的多个子区域里,可以用
TPad来分割画布,修改一下遍历部分的代码就行 - 可以根据需求调整标记样式(比如
SetMarkerStyle(21)是方形)、颜色(ROOT有预定义的颜色常量如kGreen、kBlack)等
内容的提问来源于stack exchange,提问作者 Lamya
相关产品推荐
相关产品推荐

