Hi,
I have coded a function which allows me to easily plot columns of a TDataFrame by passing as argument the TDataFrame and the names of the columns to plot (if only one column is given it is supposed to be the y values and the abcissa values are generated as an integer sequence).
It reads like this:
using namespace ROOT::Experimental;
void plot_df(TDataFrame& tdf, const std::string& ycol,
const std::string& xcol = "",
const std::string& options = "A*")
{
int argc{1};
char* argv[] = {(char *)""};
TApplication theApp("tapp", &argc, argv);
TCanvas c1("c1");
c1.SetGrid();
TGraph g{};
auto y = *(tdf.Take<double>(ycol));
std::vector<double> x(y.size());
std::iota(x.begin(), x.end(), 0.);
if(xcol != "")
{
x = *(tdf.Take<double>(xcol));
g = TGraph(y.size(), &x[0], &y[0]);
}
else
{
g = TGraph(y.size(), &x[0], &y[0]);
}
g.Draw(options.c_str());
g.SetMarkerStyle(21);
c1.Update();
theApp.Run();
}
I can therefore do this and it works:
int main(int argc, char* argv[])
{
auto fileName = "../data/input_samples.csv";
auto tdf = ROOT::Experimental::TDF::MakeCsvDataFrame(fileName);
plot_df(tdf,"landsat8_b5_20140729","landsat8_b6_20140729") ;
return 0;
}
However, if instead of passing the TDataFrame, I pass the result of a filter, like
plot_df(tdf.Filter("code==211"),"landsat8_b5_20140729","landsat8_b6_20140729") ;
I get this error because of course the type does not fit:
/home/garjola/Dev/RootLearning/sql/scatterplot-dataframe.cxx: In function ‘int main(int, char**)’:
/home/garjola/Dev/RootLearning/sql/scatterplot-dataframe.cxx:41:21: error: invalid initialization of non-const reference of type ‘ROOT::Experimental::TDataFrame&’ from an rvalue of type ‘ROOT::Experimental::TDF::TInterface<ROOT::Detail::TDF::TFilterBase>’
plot_df(tdf.Filter("code==211"),"landsat8_b5_20140729","landsat8_b6_20140729") ;
~~~~~~~~~~^~~~~~~~~~~~~
/home/garjola/Dev/RootLearning/sql/scatterplot-dataframe.cxx:9:6: note: in passing argument 1 of ‘void plot_df(ROOT::Experimental::TDataFrame&, const string&, const string&, const string&)’
void plot_df(TDataFrame& tdf, const std::string& ycol,
^~~~~~~
If I change the function signature to this
void plot_df(auto& tdf, const std::string& ycol,
const std::string& xcol = "",
const std::string& options = "A*")
or this
template <typename T>
void plot_df(T& tdf, const std::string& ycol,
const std::string& xcol = "", const std::string& options = "A*")
I get this error:
/home/garjola/Dev/RootLearning/sql/scatterplot-dataframe.cxx: In function ‘void plot_df(T&, const string&, const string&, const string&)’:
/home/garjola/Dev/RootLearning/sql/scatterplot-dataframe.cxx:20:23: error: expected primary-expression before ‘double’
auto y = *(tdf.Take<double>(ycol));
^~~~~~
/home/garjola/Dev/RootLearning/sql/scatterplot-dataframe.cxx:20:23: error: expected ‘)’ before ‘double’
/home/garjola/Dev/RootLearning/sql/scatterplot-dataframe.cxx:25:20: error: expected primary-expression before ‘double’
x = *(tdf.Take<double>(xcol));
^~~~~~
/home/garjola/Dev/RootLearning/sql/scatterplot-dataframe.cxx:25:20: error: expected ‘)’ before ‘double’
So I don’t know how to build a generic function which can be used with the result of a transformation. I was assuming that the “Take” action inside the function would allow to trigger the transformation. Also, I don’t understand why the code works if I copy the body of the function inside main() like this:
int main(int argc, char* argv[])
{
auto fileName = "../data/input_samples.csv";
auto tdf = ROOT::Experimental::TDF::MakeCsvDataFrame(fileName);
auto tdff = tdf.Filter("code==211");
TApplication theApp("tapp", &argc, argv);
TCanvas c1("c1");
c1.SetGrid();
TGraph g{};
std::string ycol = "landsat8_b5_20140729";
std::string xcol = "landsat8_b6_20140729";
std::string options = "A*";
auto y = *(tdff.Take<double>(ycol));
std::vector<double> x(y.size());
std::iota(x.begin(), x.end(), 0.);
if(xcol != "")
{
x = *(tdff.Take<double>(xcol));
g = TGraph(y.size(), &x[0], &y[0]);
}
else
{
g = TGraph(y.size(), &x[0], &y[0]);
}
g.Draw(options.c_str());
g.SetMarkerStyle(21);
c1.Update();
theApp.Run();
return 0;
}
Any hint is welcome.
Thanks.
Garjola