cepgen
is hosted by
Hepforge
,
IPPP Durham
CepGen
1.2.5
Central exclusive processes event generator
Loading...
Searching...
No Matches
MatplotlibDrawer.cpp
Go to the documentation of this file.
1
/*
2
* CepGen: a central exclusive processes event generator
3
* Copyright (C) 2022 Laurent Forthomme
4
*
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* any later version.
9
*
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
#include <matplotlibcpp.h>
20
21
#include "
CepGen/Modules/DrawerFactory.h
"
22
#include "
CepGen/Utils/Drawer.h
"
23
#include "
CepGen/Utils/Graph.h
"
24
#include "
CepGen/Utils/Histogram.h
"
25
#include "
CepGen/Utils/Message.h
"
26
#include "
CepGen/Version.h
"
27
28
namespace
plt = matplotlibcpp;
29
30
namespace
cepgen
{
31
namespace
utils {
32
class
MatplotlibDrawer
:
public
Drawer
{
33
public
:
34
explicit
MatplotlibDrawer
(
const
ParametersList
&);
35
36
static
ParametersDescription
description
() {
37
auto
desc =
Drawer::description
();
38
desc.setDescription(
"Matplotlib plotter"
);
39
desc.add<
bool
>(
"tight"
,
false
).setDescription(
"use a compact layout with minimal margins"
);
40
return
desc;
41
}
42
43
const
MatplotlibDrawer
&
draw
(
const
Graph1D
&,
const
Mode&)
const override
;
44
const
MatplotlibDrawer
&
draw
(
const
Graph2D
&,
const
Mode&)
const override
;
45
const
MatplotlibDrawer
&
draw
(
const
Hist1D
&,
const
Mode&)
const override
;
46
const
MatplotlibDrawer
&
draw
(
const
Hist2D
&,
const
Mode&)
const override
;
47
48
const
MatplotlibDrawer
&
draw
(
const
DrawableColl
&,
49
const
std::string&
name
=
""
,
50
const
std::string& title =
""
,
51
const
Mode& mode = Mode::none)
const override
;
52
53
private
:
54
static
void
plot(
const
Graph1D
&,
const
Mode&);
55
static
void
plot(
const
Graph2D
&,
const
Mode&);
56
static
void
plot(
const
Hist1D
&,
const
Mode&);
57
void
postDraw(
const
Drawable
&,
const
Mode&)
const
;
58
const
bool
tight_;
59
};
60
61
MatplotlibDrawer::MatplotlibDrawer
(
const
ParametersList
& params) :
Drawer
(params), tight_(steer<bool>(
"tight"
)) {}
62
63
const
MatplotlibDrawer
&
MatplotlibDrawer::draw
(
const
Graph1D
& graph,
const
Mode
& mode)
const
{
64
plt::figure();
65
plot(graph, mode);
66
postDraw(graph, mode);
67
plt::title(graph.
title
());
68
plt::save(graph.
name
() +
".pdf"
);
69
return
*
this
;
70
}
71
72
const
MatplotlibDrawer
&
MatplotlibDrawer::draw
(
const
Graph2D
& graph,
const
Mode
& mode)
const
{
73
plt::figure();
74
plot(graph, mode);
75
postDraw(graph, mode);
76
plt::title(graph.
title
());
77
plt::save(graph.
name
() +
".pdf"
);
78
return
*
this
;
79
}
80
81
const
MatplotlibDrawer
&
MatplotlibDrawer::draw
(
const
Hist1D
& hist,
const
Mode
& mode)
const
{
82
plt::figure();
83
plot(hist, mode);
84
postDraw(hist, mode);
85
plt::title(hist.
title
());
86
plt::save(hist.
name
() +
".pdf"
);
87
return
*
this
;
88
}
89
90
const
MatplotlibDrawer
&
MatplotlibDrawer::draw
(
const
Hist2D
&,
const
Mode
&)
const
{
91
CG_WARNING
(
"MatplotlibDrawer:draw"
) <<
"Not yet implemented."
;
92
return
*
this
;
93
}
94
95
const
MatplotlibDrawer
&
MatplotlibDrawer::draw
(
const
DrawableColl
& objs,
96
const
std::string& name,
97
const
std::string& title,
98
const
Mode
& mode)
const
{
99
try
{
100
plt::figure();
101
const
Drawable
* first_obj =
nullptr
;
102
for
(
const
auto
* obj : objs)
103
if
(obj->isHist1D()) {
104
auto
* hist =
dynamic_cast<
const
Hist1D
*
>
(obj);
105
plot(*hist, mode);
106
if
(!first_obj)
107
first_obj = hist;
108
}
else
if
(obj->isGraph1D()) {
109
auto
* gr =
dynamic_cast<
const
Graph1D
*
>
(obj);
110
plot(*gr, mode);
111
if
(!first_obj)
112
first_obj = gr;
113
}
114
if
(!title.empty())
115
plt::title(title);
116
if
(first_obj)
117
postDraw(*first_obj, mode);
118
if
(objs.size() > 1)
119
plt::legend();
120
plt::save(
name
+
".pdf"
);
121
}
catch
(
const
std::runtime_error& err) {
122
CG_WARNING
(
"MatplotlibDrawer:draw"
) <<
"Failed to draw a plots collection. Matplotlib error: "
<< err.what();
123
}
124
return
*
this
;
125
}
126
127
void
MatplotlibDrawer::plot(
const
Graph1D
& gr,
const
Mode& mode) {
128
std::vector<double> x, y, xerr, yerr;
129
for
(
const
auto
& pt : gr.points()) {
130
x.emplace_back(pt.first.value);
131
y.emplace_back(pt.second);
132
xerr.emplace_back(pt.first.value_unc);
133
yerr.emplace_back(pt.second.uncertainty());
134
}
135
if
((mode & Mode::logx) && (mode & Mode::logy))
136
plt::named_loglog(gr.
title
(), x, y);
137
else
if
(mode & Mode::logx)
138
plt::named_semilogx(gr.
title
(), x, y);
139
else
if
(mode & Mode::logy)
140
plt::named_semilogy(gr.
title
(), x, y);
141
else
if
(yerr != std::vector<double>(yerr.size(), 0.))
142
plt::errorbar(x, y, yerr, {{
"label"
, gr.
title
()}, {
"linestyle"
,
""
}});
143
else
144
plt::plot(x, y, {{
"label"
, gr.
title
()}});
145
}
146
147
void
MatplotlibDrawer::plot(
const
Graph2D& gr,
const
Mode&) {
148
std::vector<std::vector<double> > x, y, z;
149
for
(
const
auto
& xv : gr.points()) {
150
const
auto
xval = xv.first.value;
151
std::vector<double> xrow, yrow, zrow;
152
for
(
const
auto
& yv : xv.second) {
153
xrow.emplace_back(xval);
154
yrow.emplace_back(yv.first.value);
155
zrow.emplace_back(yv.second);
156
}
157
x.emplace_back(xrow);
158
y.emplace_back(yrow);
159
z.emplace_back(zrow);
160
}
161
plt::plot_surface(x, y, z, {{
"label"
, gr.title()}});
162
//plt::contour(x, y, z, {{"label", gr.title()}});
163
plt::set_zlabel(gr.zAxis().label());
164
}
165
166
void
MatplotlibDrawer::plot(
const
Hist1D& hist,
const
Mode& mode) {
167
std::vector<double> x, y, yerr;
168
for
(
size_t
ibin = 0; ibin < hist.nbins(); ++ibin) {
169
const
auto
val = hist.value(ibin);
170
x.emplace_back(hist.binRange(ibin).x(0.5));
171
y.emplace_back(val);
172
yerr.emplace_back(val.uncertainty());
173
}
174
//plt::bar(x, y, "", "", 1., {{"label", hist.title()}});
175
//plt::bar(x, y);
176
std::map<std::string, std::string> plot_style = {{
"label"
, hist.title()}, {
"drawstyle"
,
"steps"
}};
177
if
((mode & Mode::logx) && (mode & Mode::logy))
178
plt::named_loglog(hist.title(), x, y,
"o"
);
179
else
if
(mode & Mode::logx)
180
plt::named_semilogx(hist.title(), x, y,
"o"
);
181
else
if
(mode & Mode::logy)
182
plt::named_semilogy(hist.title(), x, y,
"o"
);
183
else
if
(!yerr.empty() && yerr != std::vector<double>(yerr.size(), 0.))
184
plt::errorbar(x, y, yerr, plot_style);
185
else
186
plt::plot(x, y, plot_style);
187
}
188
189
void
MatplotlibDrawer::postDraw(
const
Drawable& dr,
const
Mode& mode)
const
{
190
if
(mode & Mode::grid)
191
plt::grid(
true
);
192
const
auto
& yrange = dr.yAxis().range();
193
if
(yrange.valid()) {
194
auto
rng = plt::ylim();
195
if
(yrange.hasMin())
196
rng[0] = yrange.min();
197
if
(yrange.hasMax())
198
rng[1] = yrange.max();
199
try
{
200
plt::ylim(rng.at(0), rng.at(1));
201
}
catch
(
const
std::runtime_error& err) {
202
CG_WARNING
(
"MatplotlibDrawer:postDraw"
)
203
<<
"Failed to set Y range to "
<< rng <<
". Matplotlib error: "
<< err.what();
204
}
205
}
206
plt::xlabel(dr.xAxis().label());
207
plt::ylabel(dr.yAxis().label());
208
plt::suptitle(
"CepGen v"
+
version::tag
);
209
if
(tight_)
210
plt::tight_layout();
211
}
212
}
// namespace utils
213
}
// namespace cepgen
214
typedef
cepgen::utils::MatplotlibDrawer
MPLDrawer
;
215
REGISTER_DRAWER
(
"matplotlib"
,
MPLDrawer
);
DrawerFactory.h
REGISTER_DRAWER
#define REGISTER_DRAWER(name, obj)
Add a drawing utilitary.
Definition
DrawerFactory.h:25
Drawer.h
Graph.h
Histogram.h
MPLDrawer
cepgen::utils::MatplotlibDrawer MPLDrawer
Definition
MatplotlibDrawer.cpp:214
Message.h
CG_WARNING
#define CG_WARNING(mod)
Definition
Message.h:228
Version.h
cepgen::NamedModule< Drawer >::name
const std::string & name() const
Module unique indexing name.
Definition
NamedModule.h:42
cepgen::ParametersDescription
A description object for parameters collection.
Definition
ParametersDescription.h:26
cepgen::ParametersList
Definition
ParametersList.h:52
cepgen::Steerable::description
static ParametersDescription description()
Description of all object parameters.
Definition
Steerable.cpp:42
cepgen::utils::Drawable
A generic object which can be drawn in the standard output.
Definition
Drawable.h:31
cepgen::utils::Drawable::name
const std::string & name() const
Drawable name.
Definition
Drawable.h:37
cepgen::utils::Drawable::title
const std::string & title() const
Drawable name.
Definition
Drawable.h:42
cepgen::utils::Drawer::Mode
Definition
Drawer.h:41
cepgen::utils::Drawer
A generic drawing utility.
Definition
Drawer.h:36
cepgen::utils::Graph1D
A one-dimensional graph object.
Definition
Graph.h:29
cepgen::utils::Graph2D
A two-dimensional graph object.
Definition
Graph.h:58
cepgen::utils::Hist1D
1D histogram container
Definition
Histogram.h:72
cepgen::utils::Hist2D
2D histogram container
Definition
Histogram.h:146
cepgen::utils::MatplotlibDrawer
Definition
MatplotlibDrawer.cpp:32
cepgen::utils::MatplotlibDrawer::description
static ParametersDescription description()
Definition
MatplotlibDrawer.cpp:36
cepgen::utils::MatplotlibDrawer::MatplotlibDrawer
MatplotlibDrawer(const ParametersList &)
Definition
MatplotlibDrawer.cpp:61
cepgen::utils::MatplotlibDrawer::draw
const MatplotlibDrawer & draw(const Graph1D &, const Mode &) const override
Draw a one-dimensional graph.
Definition
MatplotlibDrawer.cpp:63
cepgen::utils::DrawableColl
std::vector< const Drawable * > DrawableColl
A collection of drawable objects.
Definition
Drawer.h:34
cepgen
Common namespace for this Monte Carlo generator.
Definition
CommandLineHandler.cpp:36
cepgen::version::tag
static const std::string tag
CepGen version.
Definition
Version.h:28
CepGenAddOns
MatplotlibWrapper
MatplotlibDrawer.cpp
Generated on Mon Jul 29 2024 for CepGen by
1.9.7