You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:13:27