Lumiera  0.pre.03
»edit your freedom«
gnuplot-gen.cpp
Go to the documentation of this file.
1 /*
2  GnuplotGen - building blocks for simplified data visualisation via Gnuplot
3 
4  Copyright (C) Lumiera.org
5  2024, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
23 
72 #include "lib/text-template.hpp"
74 #include "lib/gnuplot-gen.hpp"
75 #include "lib/format-util.hpp"
76 
77 #include <string>
78 
79 using std::string;
80 
81 
82 namespace lib {
83 namespace gnuplot_gen {
84 
85  namespace { // Template and defaults definitions for diagram generation
86 
87 
88  const string GNUPLOT_CommonStyleDef = R"~(#
89 #---common-styles-for-plots-from-Lumiera---------
90 set style line 1 linetype 1 linewidth 2 linecolor rgb '#240CC3'
91 set style line 2 linetype 3 linewidth 2 linecolor rgb '#1149D6'
92 set style line 3 linetype 2 linewidth 2 linecolor rgb '#0B7FCC'
93 set style line 4 linetype 6 linewidth 2 linecolor rgb '#37999D'
94 set style line 5 linetype 7 linewidth 2 linecolor rgb '#248269'
95 set style line 6 linetype 13 linewidth 2 linecolor rgb '#00C443'
96 set style line 7 linetype 12 linewidth 2 linecolor rgb '#EBE83E'
97 set style line 8 linetype 5 linewidth 2 linecolor rgb '#762C14'
98 set style line 9 linetype 4 linewidth 2 linecolor rgb '#AA0519'
99 
100 set style line 10 linetype 1 linewidth 1 linecolor rgb '#303030'
101 set style line 11 linetype 0 linewidth 1 linecolor rgb '#A0A0A0' dashtype 3
102 #---(End)styles----------------------------------
103 )~";
104 
105  const string GNUPLOT_AxisGridSetup = R"~(#
106 #---axis-and-grid-setup--------------------------
107 unset border
108 set tics nomirror
109 set grid back linestyle 11
110 
111 set arrow 10 from graph 0,0 to graph 1.04,0 size screen 0.025,15,60 filled ls 10
112 set arrow 11 from graph 0,0 to graph 0,1.08 size screen 0.025,15,60 filled ls 10
113 )~";
114 
115 
116  const string GNUPLOT_BASIC_PLOT_DEF = R"~(#
117 #
118 # GNUPLOT - data plot from Lumiera
119 #
120 
121 ${if Term
122 }set term ${Term} ${
123 if TermSize}size ${TermSize}${endif}
124 ${else}${if TermSize
125 }set term wxt size ${TermSize}
126 ${endif}${endif Term}
127 
128 set datafile separator ",;"
129 
130 ####---------Data--------------------------------
131 $RunData << _End_of_Data_
132 ${CSVData}
133 _End_of_Data_
134 
135 
136 ${CommonStyleDef}
137 ${AxisGridSetup}
138 
139 ${if Xlabel
140 }set xlabel '${Xlabel}'
141 ${else
142 }stats $RunData using (abscissaName=strcol(1)) every ::0::0 nooutput
143 
144 set xlabel abscissaName
145 ${end if Xlabel
146 }${if Ylabel
147 }set ylabel '${Ylabel}' ${end if Ylabel
148 }
149 ${if Xrange}
150 set xrange [${Xrange}] ${endif
151 }${if Yrange}
152 set yrange [${Yrange}] ${endif
153 }set key autotitle columnheader tmargin
154 
155 )~";
156 
157  const string GNUPLOT_SIMPLE_DATA_PLOT = R"~(#
158 ####---------------------------------------------
159 plot for [i=2:*] $RunData using 1:i with ${DiagramKind} linestyle i-1
160 
161 )~";
162 
163 
164  const string GNUPLOT_SCATTER_REGRESSION = R"~(#
165 stats $RunData using 1:2 nooutput
166 
167 ${if RegrSlope
168 }# regression line function (given as parameter)
169 regLine(x) = ${RegrSlope} * x + ${RegrSocket}
170 ${else
171 }# regression line function derived from data
172 regLine(x) = STATS_slope * x + STATS_intercept
173 ${end if
174 }#
175 regLabel = sprintf("Model: %3.2f·p + %3.2f", STATS_slope, STATS_intercept)
176 
177 set key horizontal width -4
178 ${if Xtics
179 }set xtics ${Xtics}
180 ${else}${if Xrange}${else
181 }set xrange [0:*]
182 set xtics 1
183 ${end if}${end if Xtics
184 }
185 plots = STATS_columns - 1
186 # Adjust layout based on number of data sequences;
187 # additional sequences placed into secondary diagram
188 #
189 if (plots > 1) {
190  set multiplot layout 2,1 # 2 rows 1 column
191  set lmargin at screen 0.12 # fixed margins to align diagrams
192  set rmargin at screen 0.88
193 }
194 #
195 #
196 ####---------Scatter-Regression-Plot-------------
197 plot $RunData using 1:2 with points linestyle 1, \
198  regLine(x) with line linestyle 9 title regLabel
199 
200 if (plots > 1) {
201  # switch off decorations for secondary diagram
202  unset arrow 10
203  unset arrow 11
204  set border 2+8
205  set key bmargin vertical
206 ${if Y2range}
207  set yrange [${Y2range}]
208 ${endif}
209  unset xlabel
210  set format x ""
211 ${if Y2label
212 } set ylabel '${Y2label}' ${endif
213 }
214  if (plots <= 2) {
215  ####---------------------------------
216  plot $RunData using 1:3 with impulses linestyle 3
217 
218  } else {
219  # more than one additional data sequence
220  #
221 ${if Y3range
222 } set y2range [${Y3range}]
223 
224 ${endif
225 } set y2tics
226 ${if Y3label
227 } set y2label '${Y3label}' offset -1.5
228 ${endif}
229  ####---------------------------------------------
230  plot $RunData using 1:3 with impulses linestyle 3, \
231  for [i=4:*] $RunData using 1:i with points linestyle 5+(i-4) axes x1y2
232  }
233 }
234 )~";
235 
236 
237  }//(End)template and defaults definitions
238 
239 
240 
241 
242 
249  string
251  {
252  TextTemplate plot{GNUPLOT_BASIC_PLOT_DEF
253  +GNUPLOT_SIMPLE_DATA_PLOT};
254 
255  params.set ("CommonStyleDef", GNUPLOT_CommonStyleDef)
256  .set ("AxisGridSetup", GNUPLOT_AxisGridSetup)
257  .set (KEY_DiagramKind, "points")
258  ;
259  return plot.render (params.genNode());
260  }
261 
262 
273  string
275  {
276  TextTemplate plot{GNUPLOT_BASIC_PLOT_DEF
277  +GNUPLOT_SCATTER_REGRESSION};
278 
279  params.set ("CommonStyleDef", GNUPLOT_CommonStyleDef)
280  .set ("AxisGridSetup", GNUPLOT_AxisGridSetup)
281  ;
282  return plot.render (params.genNode());
283  }
284 
285 }} // namespace lib::gnuplot_gen
Preconfigured setup for data visualisation with Gnuplot.
Text template substitution engine.
string scatterRegression(ParamRecord params)
Generate a (X,Y)-scatter plot with regression line.
string dataPlot(ParamRecord params)
Generate a Gnuplot diagram to visualise the given data points.
Implementation namespace for support and library code.
A minimalistic text templating engine with flexible data binding.
Collection of small helpers and convenience shortcuts for diagnostics & formatting.
A complement to allow instantiation of a TextTemplate with ETD data.