我想使用 CERN ROOT 来绘制一对 xy 数据点的二维图,也可能使用 y-errorbars。但是我只知道如何绘制直方图。
CERN ROOT 可以做到这一点吗?如果有怎么办?
我也意识到可能有更好的库可以做到这一点。我一直在使用 GNUPlot,但不幸的是,我似乎无法将它与我的 C++ 代码很好地集成,因为我找不到涵盖所有功能并允许我以双向方式发送数据的 C/C++ GNUPlot 接口 -即:往返 GNUPlot。
如果您有更好的替代建议,那将是最受欢迎的。
我想使用 CERN ROOT 来绘制一对 xy 数据点的二维图,也可能使用 y-errorbars。但是我只知道如何绘制直方图。
CERN ROOT 可以做到这一点吗?如果有怎么办?
我也意识到可能有更好的库可以做到这一点。我一直在使用 GNUPlot,但不幸的是,我似乎无法将它与我的 C++ 代码很好地集成,因为我找不到涵盖所有功能并允许我以双向方式发送数据的 C/C++ GNUPlot 接口 -即:往返 GNUPlot。
如果您有更好的替代建议,那将是最受欢迎的。
有gnuplot iostream可以将数据从 c++ 发送到 gnuplot。在 root 中,您可以使用(如其他人所建议的那样)TGraph
, TGraphErrors
, TGraphAsymErrors
.
编辑:
其主页上的 gnuplot iostream 示例如下所示。意味着一旦您将数据点作为一个元组向量或几个浮点向量,您可以将它们发送到 gnuplot。
#include <vector>
#include <cmath>
#include <boost/tuple/tuple.hpp>
#include "gnuplot-iostream.h"
int main() {
Gnuplot gp;
// Create a script which can be manually fed into gnuplot later:
// Gnuplot gp(">script.gp");
// Create script and also feed to gnuplot:
// Gnuplot gp("tee plot.gp | gnuplot -persist");
// Or choose any of those options at runtime by setting the GNUPLOT_IOSTREAM_CMD
// environment variable.
// Gnuplot vectors (i.e. arrows) require four columns: (x,y,dx,dy)
std::vector<boost::tuple<double, double, double, double> > pts_A;
// You can also use a separate container for each column, like so:
std::vector<double> pts_B_x;
std::vector<double> pts_B_y;
std::vector<double> pts_B_dx;
std::vector<double> pts_B_dy;
// You could also use:
// std::vector<std::vector<double> >
// boost::tuple of four std::vector's
// std::vector of std::tuple (if you have C++11)
// arma::mat (with the Armadillo library)
// blitz::Array<blitz::TinyVector<double, 4>, 1> (with the Blitz++ library)
// ... or anything of that sort
for(double alpha=0; alpha<1; alpha+=1.0/24.0) {
double theta = alpha*2.0*3.14159;
pts_A.push_back(boost::make_tuple(
cos(theta),
sin(theta),
-cos(theta)*0.1,
-sin(theta)*0.1
));
pts_B_x .push_back( cos(theta)*0.8);
pts_B_y .push_back( sin(theta)*0.8);
pts_B_dx.push_back( sin(theta)*0.1);
pts_B_dy.push_back(-cos(theta)*0.1);
}
// Don't forget to put "\n" at the end of each line!
gp << "set xrange [-2:2]\nset yrange [-2:2]\n";
// '-' means read from stdin. The send1d() function sends data to gnuplot's stdin.
gp << "plot '-' with vectors title 'pts_A', '-' with vectors title 'pts_B'\n";
gp.send1d(pts_A);
gp.send1d(boost::make_tuple(pts_B_x, pts_B_y, pts_B_dx, pts_B_dy));
return 0;
}
是的,这是可能的,你可以这样做:
// At program start
TApplication tapp("app", 0, 0); // this is needed for some reason - not ideal
// Later in program
TGraph *tgraph = new TGraph(N, x, y); // data: x,y N points
TCanvas *tcanvas = new TCanvas("tcanvas","canvas title", 200, 10, 800, 600);
tgraph->SetMarkerColor(kBlue);
tgraph->SetMarkerStyle(21);
tgraph->Draw();
tcanvas->Update();
// Wait for user to check if graph is "okay"
std::cin.get();
delete tcanvas;
delete tgraph;
**但是**此代码不会循环工作。随后的图表将是空白的。我不知道为什么。