├── sample_project.vcxproj.user
├── gnuplot-cppConfig.cmake
├── sample_project.vcxproj.filters
├── Makefile
├── runPVS_Studio.sh
├── README.md
├── gnuplot-cpp.sln
├── sample_project.vcxproj
├── example.cc
├── doc
└── Doxyfile
└── gnuplot_i.hpp
/sample_project.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/gnuplot-cppConfig.cmake:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.3.0)
2 | project("gnuplot-cpp")
3 |
4 | message(STATUS "Found gnuplot:${gnuplot-cpp_DIR}")
5 |
6 | set(gnuplot-cpp_INCLUDE_DIRS ${gnuplot-cpp_INCLUDE_DIRS} "${gnuplot-cpp_DIR}")
7 |
--------------------------------------------------------------------------------
/sample_project.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | CFLAGS = -ggdb -Wall -Wextra -pedantic -Wconversion -Wsign-conversion -O3
2 | DEFINES = -DDEBUGGA
3 | INCLUDES =
4 | LIBS = -lstdc++
5 | EXAMPLE = example.o
6 | CC=g++
7 |
8 | .cc.o:
9 | $(CC) -c $(CFLAGS) $(DEFINES) $(INCLUDES) $<
10 |
11 | all: example
12 |
13 | gnuplot_i.o: gnuplot_i.hpp
14 | example.o: example.cc
15 |
16 | example: $(EXAMPLE)
17 | $(CC) -o $@ $(CFLAGS) $(EXAMPLE) $(LIBS)
18 |
19 | clean:
20 | rm -f $(EXAMPLE) example
21 | rm -f *.orig
22 |
23 | style:
24 | /usr/bin/find . -regextype "posix-extended" -iregex '.*\.(c|cc|cxx|h|hh|hpp|cpp)' -type f -exec astyle --style=ansi -S -N -w -Y -p -C -c -j {} \;
25 |
--------------------------------------------------------------------------------
/runPVS_Studio.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # This script runs the PVS Studio analyzer
3 | # on gnuplot-cpp
4 | #
5 | # Usage:
6 | # sh runPVS_Studio.sh
7 | #
8 | # After the script has finished, take a look at p.tasks.
9 | # This file contains the checking results.
10 | #
11 | # References:
12 | # - How to run PVS-Studio on Linux: https://www.viva64.com/en/m/0036/#ID0E3DAC
13 | # - How to use PVS-Studio for Free: https://www.viva64.com/en/b/0457/
14 | # - Download PVS-Studio for Linux: https://www.viva64.com/en/pvs-studio-download-linux/
15 | #
16 |
17 | make clean # Cleanup previous build
18 | rm -fR result # Remove results
19 | rm -f p.log # Remove log file
20 | pvs-studio-analyzer trace -- make -j3 CFLAGS=""
21 | pvs-studio-analyzer analyze -o p.log
22 | plog-converter -a GA:1,2,3 -t fullhtml -o result p.log
23 | xdg-open result/index.html
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # gnuplot-cpp
2 | C++ interface to Gnuplot via POSIX pipes
3 |
4 | This project was hosted on [google code](https://code.google.com/archive/p/gnuplot-cpp/). Since google dropped google code, this project was moved to github.
5 |
6 |
7 | 
8 |
9 | # Use with CMake Projects
10 |
11 | To use this interface within your CMake projects, you can use the gnuplot-cppConfig.cmake. Just make sure, that CMake is able to find the gnuplot-cpp directory, either by moving it to the CMake search path, or setting graybat-cpp_dir.
12 |
13 | To include it into your project just add:
14 | ```
15 | find_package(gnuplot-cpp REQUIRED)
16 | include_directories(${gnuplot-cpp_INCLUDE_DIRS})
17 | ```
18 |
--------------------------------------------------------------------------------
/gnuplot-cpp.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27004.2005
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_project", "sample_project.vcxproj", "{903BC4A3-AD97-4569-8B6A-6A5D58768601}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Release|Win32 = Release|Win32
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {903BC4A3-AD97-4569-8B6A-6A5D58768601}.Debug|Win32.ActiveCfg = Debug|Win32
15 | {903BC4A3-AD97-4569-8B6A-6A5D58768601}.Debug|Win32.Build.0 = Debug|Win32
16 | {903BC4A3-AD97-4569-8B6A-6A5D58768601}.Release|Win32.ActiveCfg = Release|Win32
17 | {903BC4A3-AD97-4569-8B6A-6A5D58768601}.Release|Win32.Build.0 = Release|Win32
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {BB6E9203-F689-4515-BCFD-047A8A3EDE0A}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/sample_project.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | {903BC4A3-AD97-4569-8B6A-6A5D58768601}
21 | Win32Proj
22 | sample_project
23 | 8.1
24 | gnuplot-cpp
25 |
26 |
27 |
28 | Application
29 | true
30 | Unicode
31 | v141
32 |
33 |
34 | Application
35 | false
36 | true
37 | Unicode
38 | v141
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | false
52 | ..\bin\
53 | $(Configuration)\$(ProjectName)\
54 | AllRules.ruleset
55 | false
56 |
57 |
58 | false
59 | ..\bin\
60 | $(Configuration)\$(ProjectName)\
61 | AllRules.ruleset
62 | false
63 |
64 |
65 |
66 |
67 |
68 | Level4
69 | Disabled
70 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS
71 | /FS %(AdditionalOptions)
72 |
73 |
74 | Console
75 | true
76 | Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
77 |
78 |
79 |
80 |
81 | Level4
82 |
83 |
84 | MaxSpeed
85 | true
86 | true
87 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS
88 | /FS
89 |
90 |
91 | Console
92 | true
93 | true
94 | true
95 | Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/example.cc:
--------------------------------------------------------------------------------
1 | // This is an open source non-commercial project. Dear PVS-Studio, please check it.
2 | // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
3 |
4 | // Example for C++ Interface to Gnuplot
5 |
6 | // requirements:
7 | // * gnuplot has to be installed (http://www.gnuplot.info/download.html)
8 | // * for Windows: set Path-Variable for Gnuplot path (e.g. C:/program files/gnuplot/bin)
9 | // or set Gnuplot path with: Gnuplot::set_GNUPlotPath(const std::string &path);
10 |
11 |
12 | #include
13 | #include "gnuplot_i.hpp" //Gnuplot class handles POSIX-Pipe-communication with Gnuplot
14 |
15 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
16 | #include //for getch(), needed in wait_for_key()
17 | #include //for Sleep()
18 | #endif
19 |
20 |
21 | #define NPOINTS 50 // length of array
22 |
23 | static void wait_for_key(void); // Program halts until keypress
24 |
25 | using std::cout;
26 | using std::endl;
27 |
28 | int main(void)
29 | {
30 | // if path-variable for gnuplot is not set, do it with:
31 | // Gnuplot::set_GNUPlotPath("C:/program files/gnuplot/bin/");
32 |
33 | #if defined(__APPLE__)
34 | // set a special standard terminal for showonscreen (normally not needed),
35 | // e.g. Mac users who want to use x11 instead of aqua terminal:
36 | Gnuplot::set_terminal_std("x11");
37 | #endif
38 | cout << "*** example of gnuplot control through C++ ***" << endl << endl;
39 |
40 | //
41 | // Using the GnuplotException class
42 | //
43 | try
44 | {
45 | Gnuplot g1("lines");
46 |
47 | //
48 | // Slopes
49 | //
50 | cout << "*** plotting slopes" << endl;
51 | g1.set_title("Slopes\\nNew Line");
52 |
53 | cout << "y = x" << endl;
54 | g1.plot_slope(1.0, 0.0, "y=x");
55 |
56 | cout << "y = 2*x" << endl;
57 | g1.plot_slope(2.0, 0.0, "y=2x");
58 |
59 | cout << "y = -x" << endl;
60 | g1.plot_slope(-1.0, 0.0, "y=-x");
61 | g1.unset_title();
62 |
63 | //
64 | // Equations
65 | //
66 | g1.reset_plot();
67 | cout << endl << endl << "*** various equations" << endl;
68 |
69 | cout << "y = sin(x)" << endl;
70 | g1.plot_equation("sin(x)", "sine");
71 |
72 | cout << "y = log(x)" << endl;
73 | g1.plot_equation("log(x)", "logarithm");
74 |
75 | cout << "y = sin(x) * cos(2*x)" << endl;
76 | g1.plot_equation("sin(x)*cos(2*x)", "sine product");
77 |
78 | //
79 | // Styles
80 | //
81 | g1.reset_plot();
82 | cout << endl << endl << "*** showing styles" << endl;
83 |
84 | cout << "sine in points" << endl;
85 | g1.set_pointsize(0.8).set_style("points");
86 | g1.plot_equation("sin(x)", "points");
87 |
88 | cout << "sine in impulses" << endl;
89 | g1.set_style("impulses");
90 | g1.plot_equation("sin(x)", "impulses");
91 |
92 | cout << "sine in steps" << endl;
93 | g1.set_style("steps");
94 | g1.plot_equation("sin(x)", "steps");
95 |
96 | //
97 | // Save to ps
98 | //
99 | g1.reset_all();
100 | cout << endl << endl << "*** save to ps " << endl;
101 |
102 | cout << "y = sin(x) saved to test_output.ps in working directory" << endl;
103 | // g1.savetops("test_output");
104 | g1.savetofigure("test_output.ps", "postscript color");
105 | g1.set_style("lines").set_samples(300).set_xrange(0, 5);
106 | g1.plot_equation("sin(12*x)*exp(-x)").plot_equation("exp(-x)");
107 |
108 | g1.showonscreen(); // window output
109 |
110 |
111 | //
112 | // User defined 1d, 2d and 3d point sets
113 | //
114 | std::vector x;
115 | std::vector y;
116 | std::vector y2;
117 | std::vector dy;
118 | std::vector z;
119 |
120 | for (unsigned int i = 0; i < NPOINTS; ++i) // fill double arrays x, y, z
121 | {
122 | x.push_back((double)i); // x[i] = i
123 | y.push_back((double)i * (double)i); // y[i] = i^2
124 | z.push_back( x[i]*y[i] ); // z[i] = x[i]*y[i] = i^3
125 | dy.push_back((double)i * (double)i / (double) 10); // dy[i] = i^2 / 10
126 | }
127 | y2.push_back(0.00);
128 | y2.push_back(0.78);
129 | y2.push_back(0.97);
130 | y2.push_back(0.43);
131 | y2.push_back(-0.44);
132 | y2.push_back(-0.98);
133 | y2.push_back(-0.77);
134 | y2.push_back(0.02);
135 |
136 |
137 | g1.reset_all();
138 | cout << endl << endl << "*** user-defined lists of doubles" << endl;
139 | g1.set_style("impulses").plot_x(y, "user-defined doubles");
140 |
141 | g1.reset_plot();
142 | cout << endl << endl << "*** user-defined lists of points (x,y)" << endl;
143 | g1.set_grid();
144 | g1.set_style("points").plot_xy(x, y, "user-defined points 2d");
145 |
146 | g1.reset_plot();
147 | cout << endl << endl << "*** user-defined lists of points (x,y,z)" << endl;
148 | g1.unset_grid();
149 | g1.plot_xyz(x, y, z, "user-defined points 3d");
150 |
151 | g1.reset_plot();
152 | cout << endl << endl << "*** user-defined lists of points (x,y,dy)" << endl;
153 | g1.plot_xy_err(x, y, dy, "user-defined points 2d with errorbars");
154 |
155 |
156 | //
157 | // Multiple output screens
158 | //
159 | cout << endl << endl;
160 | cout << "*** multiple output windows" << endl;
161 |
162 | g1.reset_plot();
163 | g1.set_style("lines");
164 | cout << "window 1: sin(x)" << endl;
165 | g1.set_grid().set_samples(600).set_xrange(0, 300);
166 | g1.plot_equation("sin(x)+sin(x*1.1)");
167 |
168 | (void)g1.set_xautoscale().replot();
169 |
170 | Gnuplot g2;
171 | cout << "window 2: user defined points" << endl;
172 | g2.plot_x(y2, "points");
173 | g2.set_smooth().plot_x(y2, "cspline");
174 | g2.set_smooth("bezier").plot_x(y2, "bezier");
175 | g2.unset_smooth();
176 |
177 | Gnuplot g3("lines");
178 | cout << "window 3: log(x)/x" << endl;
179 | g3.set_grid();
180 | g3.plot_equation("log(x)/x", "log(x)/x");
181 |
182 | Gnuplot g4("lines");
183 | cout << "window 4: splot x*x+y*y" << endl;
184 | g4.set_zrange(0, 100);
185 | g4.set_xlabel("x-axis").set_ylabel("y-axis").set_zlabel("z-axis");
186 | g4.plot_equation3d("x*x+y*y");
187 |
188 | Gnuplot g5("lines");
189 | cout << "window 5: splot with hidden3d" << endl;
190 | (void)g5.set_isosamples(25).set_hidden3d();
191 | g5.plot_equation3d("x*y*y");
192 |
193 | Gnuplot g6("lines");
194 | cout << "window 6: splot with contour" << endl;
195 | g6.set_isosamples(60).set_contour();
196 | g6.unset_surface().plot_equation3d("sin(x)*sin(y)+4");
197 |
198 | (void)g6.set_surface().replot();
199 |
200 | Gnuplot g7("lines");
201 | cout << "window 7: set_samples" << endl;
202 | g7.set_xrange(-30, 20).set_samples(40);
203 | g7.plot_equation("besj0(x)*0.12e1").plot_equation("(x**besj0(x))-2.5");
204 |
205 | (void)g7.set_samples(400).replot();
206 |
207 | Gnuplot g8("filledcurves");
208 | cout << "window 8: filledcurves" << endl;
209 | g8.set_legend("outside right top").set_xrange(-5, 5);
210 | g8.plot_equation("x*x").plot_equation("-x*x+4");
211 |
212 | //
213 | // Plot an image
214 | //
215 | Gnuplot g9;
216 | cout << "window 9: plot_image" << endl;
217 | constexpr const int unsigned uiWidth = 255U;
218 | constexpr const int unsigned uiHeight = 255U;
219 | g9.set_xrange(0, uiWidth).set_yrange(0, uiHeight).set_cbrange(0, 255);
220 | g9.cmd("set palette gray");
221 | unsigned char ucPicBuf[uiWidth * uiHeight];
222 | // generate a greyscale image
223 | for(unsigned int uiIndex = 0; uiIndex < uiHeight * uiWidth; ++uiIndex)
224 | {
225 | ucPicBuf[uiIndex] = static_cast(uiIndex % 255U);
226 | }
227 | g9.plot_image(ucPicBuf, uiWidth, uiHeight, "greyscale");
228 |
229 | g9.set_pointsize(0.6).unset_legend().plot_slope(0.8, 20);
230 |
231 | //
232 | // manual control
233 | //
234 | Gnuplot g10;
235 | cout << "window 10: manual control" << endl;
236 | g10.cmd("set samples 400").cmd("plot abs(x)/2"); // either with cmd()
237 | g10 << "replot sqrt(x)";
238 | g10 << "replot sqrt(-x)";
239 |
240 | wait_for_key();
241 | }
242 | catch (GnuplotException &ge)
243 | {
244 | cout << ge.what() << endl;
245 | }
246 |
247 |
248 | cout << endl << "*** end of gnuplot example" << endl;
249 |
250 | return 0;
251 | }
252 |
253 |
254 |
255 | static void wait_for_key (void)
256 | {
257 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) // every keypress registered, also arrow keys
258 | std::cout << std::endl << "Press any key to continue..." << std::endl;
259 |
260 | FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
261 | (void)_getch();
262 | #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
263 | std::cout << std::endl << "Press ENTER to continue..." << std::endl;
264 |
265 | std::cin.clear();
266 | std::cin.ignore(std::cin.rdbuf()->in_avail());
267 | (void)std::cin.get();
268 | #endif
269 | }
270 |
--------------------------------------------------------------------------------
/doc/Doxyfile:
--------------------------------------------------------------------------------
1 | # Doxyfile 1.5.6
2 |
3 | #---------------------------------------------------------------------------
4 | # Project related configuration options
5 | #---------------------------------------------------------------------------
6 | DOXYFILE_ENCODING = UTF-8
7 | PROJECT_NAME = gnuplot-cpp
8 | PROJECT_NUMBER = 0.9
9 | OUTPUT_DIRECTORY = ./
10 | CREATE_SUBDIRS = YES
11 | OUTPUT_LANGUAGE = English
12 | BRIEF_MEMBER_DESC = YES
13 | REPEAT_BRIEF = YES
14 | ABBREVIATE_BRIEF =
15 | ALWAYS_DETAILED_SEC = NO
16 | INLINE_INHERITED_MEMB = NO
17 | FULL_PATH_NAMES = NO
18 | STRIP_FROM_PATH =
19 | STRIP_FROM_INC_PATH =
20 | SHORT_NAMES = NO
21 | JAVADOC_AUTOBRIEF = NO
22 | QT_AUTOBRIEF = NO
23 | MULTILINE_CPP_IS_BRIEF = NO
24 | DETAILS_AT_TOP = NO
25 | INHERIT_DOCS = YES
26 | SEPARATE_MEMBER_PAGES = NO
27 | TAB_SIZE = 8
28 | ALIASES =
29 | OPTIMIZE_OUTPUT_FOR_C = NO
30 | OPTIMIZE_OUTPUT_JAVA = NO
31 | OPTIMIZE_FOR_FORTRAN = NO
32 | OPTIMIZE_OUTPUT_VHDL = NO
33 | BUILTIN_STL_SUPPORT = NO
34 | CPP_CLI_SUPPORT = NO
35 | SIP_SUPPORT = NO
36 | IDL_PROPERTY_SUPPORT = YES
37 | DISTRIBUTE_GROUP_DOC = NO
38 | SUBGROUPING = YES
39 | TYPEDEF_HIDES_STRUCT = NO
40 | #---------------------------------------------------------------------------
41 | # Build related configuration options
42 | #---------------------------------------------------------------------------
43 | EXTRACT_ALL = YES
44 | EXTRACT_PRIVATE = NO
45 | EXTRACT_STATIC = NO
46 | EXTRACT_LOCAL_CLASSES = YES
47 | EXTRACT_LOCAL_METHODS = NO
48 | EXTRACT_ANON_NSPACES = NO
49 | HIDE_UNDOC_MEMBERS = NO
50 | HIDE_UNDOC_CLASSES = NO
51 | HIDE_FRIEND_COMPOUNDS = NO
52 | HIDE_IN_BODY_DOCS = NO
53 | INTERNAL_DOCS = NO
54 | CASE_SENSE_NAMES = NO
55 | HIDE_SCOPE_NAMES = NO
56 | SHOW_INCLUDE_FILES = YES
57 | INLINE_INFO = YES
58 | SORT_MEMBER_DOCS = YES
59 | SORT_BRIEF_DOCS = NO
60 | SORT_GROUP_NAMES = NO
61 | SORT_BY_SCOPE_NAME = NO
62 | GENERATE_TODOLIST = YES
63 | GENERATE_TESTLIST = YES
64 | GENERATE_BUGLIST = YES
65 | GENERATE_DEPRECATEDLIST= YES
66 | ENABLED_SECTIONS =
67 | MAX_INITIALIZER_LINES = 30
68 | SHOW_USED_FILES = YES
69 | SHOW_DIRECTORIES = NO
70 | SHOW_FILES = YES
71 | SHOW_NAMESPACES = YES
72 | FILE_VERSION_FILTER =
73 | #---------------------------------------------------------------------------
74 | # configuration options related to warning and progress messages
75 | #---------------------------------------------------------------------------
76 | QUIET = NO
77 | WARNINGS = YES
78 | WARN_IF_UNDOCUMENTED = YES
79 | WARN_IF_DOC_ERROR = YES
80 | WARN_NO_PARAMDOC = NO
81 | WARN_FORMAT = "$file:$line: $text"
82 | WARN_LOGFILE =
83 | #---------------------------------------------------------------------------
84 | # configuration options related to the input files
85 | #---------------------------------------------------------------------------
86 | INPUT = ../
87 | INPUT_ENCODING = UTF-8
88 | FILE_PATTERNS =
89 | RECURSIVE = NO
90 | EXCLUDE =
91 | EXCLUDE_SYMLINKS = NO
92 | EXCLUDE_PATTERNS =
93 | EXCLUDE_SYMBOLS =
94 | EXAMPLE_PATH = ../example.cc
95 | EXAMPLE_PATTERNS =
96 | EXAMPLE_RECURSIVE = NO
97 | IMAGE_PATH =
98 | INPUT_FILTER =
99 | FILTER_PATTERNS =
100 | FILTER_SOURCE_FILES = NO
101 | #---------------------------------------------------------------------------
102 | # configuration options related to source browsing
103 | #---------------------------------------------------------------------------
104 | SOURCE_BROWSER = YES
105 | INLINE_SOURCES = YES
106 | STRIP_CODE_COMMENTS = YES
107 | REFERENCED_BY_RELATION = YES
108 | REFERENCES_RELATION = YES
109 | REFERENCES_LINK_SOURCE = YES
110 | USE_HTAGS = NO
111 | VERBATIM_HEADERS = YES
112 | #---------------------------------------------------------------------------
113 | # configuration options related to the alphabetical class index
114 | #---------------------------------------------------------------------------
115 | ALPHABETICAL_INDEX = NO
116 | COLS_IN_ALPHA_INDEX = 5
117 | IGNORE_PREFIX =
118 | #---------------------------------------------------------------------------
119 | # configuration options related to the HTML output
120 | #---------------------------------------------------------------------------
121 | GENERATE_HTML = YES
122 | HTML_OUTPUT = html
123 | HTML_FILE_EXTENSION = .html
124 | HTML_HEADER =
125 | HTML_FOOTER =
126 | HTML_STYLESHEET =
127 | HTML_ALIGN_MEMBERS = YES
128 | GENERATE_HTMLHELP = NO
129 | GENERATE_DOCSET = NO
130 | DOCSET_FEEDNAME = "Doxygen generated docs"
131 | DOCSET_BUNDLE_ID = org.doxygen.Project
132 | HTML_DYNAMIC_SECTIONS = NO
133 | CHM_FILE =
134 | HHC_LOCATION =
135 | GENERATE_CHI = NO
136 | CHM_INDEX_ENCODING =
137 | BINARY_TOC = NO
138 | TOC_EXPAND = NO
139 | DISABLE_INDEX = NO
140 | ENUM_VALUES_PER_LINE = 4
141 | GENERATE_TREEVIEW = NO
142 | TREEVIEW_WIDTH = 250
143 | FORMULA_FONTSIZE = 10
144 | #---------------------------------------------------------------------------
145 | # configuration options related to the LaTeX output
146 | #---------------------------------------------------------------------------
147 | GENERATE_LATEX = YES
148 | LATEX_OUTPUT = latex
149 | LATEX_CMD_NAME = latex
150 | MAKEINDEX_CMD_NAME = makeindex
151 | COMPACT_LATEX = NO
152 | PAPER_TYPE = a4wide
153 | EXTRA_PACKAGES =
154 | LATEX_HEADER =
155 | PDF_HYPERLINKS = NO
156 | USE_PDFLATEX = YES
157 | LATEX_BATCHMODE = NO
158 | LATEX_HIDE_INDICES = NO
159 | #---------------------------------------------------------------------------
160 | # configuration options related to the RTF output
161 | #---------------------------------------------------------------------------
162 | GENERATE_RTF = NO
163 | RTF_OUTPUT = rtf
164 | COMPACT_RTF = NO
165 | RTF_HYPERLINKS = NO
166 | RTF_STYLESHEET_FILE =
167 | RTF_EXTENSIONS_FILE =
168 | #---------------------------------------------------------------------------
169 | # configuration options related to the man page output
170 | #---------------------------------------------------------------------------
171 | GENERATE_MAN = NO
172 | MAN_OUTPUT = man
173 | MAN_EXTENSION = .3
174 | MAN_LINKS = NO
175 | #---------------------------------------------------------------------------
176 | # configuration options related to the XML output
177 | #---------------------------------------------------------------------------
178 | GENERATE_XML = NO
179 | XML_OUTPUT = xml
180 | XML_SCHEMA =
181 | XML_DTD =
182 | XML_PROGRAMLISTING = YES
183 | #---------------------------------------------------------------------------
184 | # configuration options for the AutoGen Definitions output
185 | #---------------------------------------------------------------------------
186 | GENERATE_AUTOGEN_DEF = NO
187 | #---------------------------------------------------------------------------
188 | # configuration options related to the Perl module output
189 | #---------------------------------------------------------------------------
190 | GENERATE_PERLMOD = NO
191 | PERLMOD_LATEX = NO
192 | PERLMOD_PRETTY = YES
193 | PERLMOD_MAKEVAR_PREFIX =
194 | #---------------------------------------------------------------------------
195 | # Configuration options related to the preprocessor
196 | #---------------------------------------------------------------------------
197 | ENABLE_PREPROCESSING = YES
198 | MACRO_EXPANSION = NO
199 | EXPAND_ONLY_PREDEF = NO
200 | SEARCH_INCLUDES = YES
201 | INCLUDE_PATH =
202 | INCLUDE_FILE_PATTERNS =
203 | PREDEFINED =
204 | EXPAND_AS_DEFINED =
205 | SKIP_FUNCTION_MACROS = YES
206 | #---------------------------------------------------------------------------
207 | # Configuration::additions related to external references
208 | #---------------------------------------------------------------------------
209 | TAGFILES =
210 | GENERATE_TAGFILE =
211 | ALLEXTERNALS = NO
212 | EXTERNAL_GROUPS = YES
213 | PERL_PATH = /usr/bin/perl
214 | #---------------------------------------------------------------------------
215 | # Configuration options related to the dot tool
216 | #---------------------------------------------------------------------------
217 | CLASS_DIAGRAMS = YES
218 | MSCGEN_PATH =
219 | HIDE_UNDOC_RELATIONS = YES
220 | HAVE_DOT = NO
221 | DOT_FONTNAME = FreeSans
222 | DOT_FONTPATH =
223 | CLASS_GRAPH = YES
224 | COLLABORATION_GRAPH = YES
225 | GROUP_GRAPHS = YES
226 | UML_LOOK = NO
227 | TEMPLATE_RELATIONS = NO
228 | INCLUDE_GRAPH = YES
229 | INCLUDED_BY_GRAPH = YES
230 | CALL_GRAPH = NO
231 | CALLER_GRAPH = NO
232 | GRAPHICAL_HIERARCHY = YES
233 | DIRECTORY_GRAPH = YES
234 | DOT_IMAGE_FORMAT = png
235 | DOT_PATH =
236 | DOTFILE_DIRS =
237 | DOT_GRAPH_MAX_NODES = 50
238 | MAX_DOT_GRAPH_DEPTH = 0
239 | DOT_TRANSPARENT = YES
240 | DOT_MULTI_TARGETS = NO
241 | GENERATE_LEGEND = YES
242 | DOT_CLEANUP = YES
243 | #---------------------------------------------------------------------------
244 | # Configuration::additions related to the search engine
245 | #---------------------------------------------------------------------------
246 | SEARCHENGINE = NO
247 |
--------------------------------------------------------------------------------
/gnuplot_i.hpp:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | ///
3 | /// \brief A C++ interface to gnuplot.
4 | ///
5 | ///
6 | /// The interface uses pipes and so won't run on a system that doesn't have
7 | /// POSIX pipe support Tested on Windows (MinGW and Visual C++) and Linux (GCC)
8 | ///
9 | /// Version history:
10 | /// 0. C interface
11 | /// by N. Devillard (27/01/03)
12 | /// 1. C++ interface: direct translation from the C interface
13 | /// by Rajarshi Guha (07/03/03)
14 | /// 2. corrections for Win32 compatibility
15 | /// by V. Chyzhdzenka (20/05/03)
16 | /// 3. some member functions added, corrections for Win32 and Linux
17 | /// compatibility
18 | /// by M. Burgis (10/03/08)
19 | ///
20 | /// Requirements:
21 | /// * gnuplot has to be installed (http://www.gnuplot.info/download.html)
22 | /// * for Windows: set Path-Variable for Gnuplot path
23 | /// (e.g. C:/program files/gnuplot/bin)
24 | /// or set Gnuplot path with:
25 | /// Gnuplot::set_GNUPlotPath(const std::string &path);
26 | ///
27 | ////////////////////////////////////////////////////////////////////////////////
28 |
29 |
30 | #ifndef GNUPLOT_I_HPP
31 | #define GNUPLOT_I_HPP
32 |
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include // for std::ostringstream
38 | #include
39 | #include // for getenv()
40 | #include // for std::list
41 |
42 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
43 | //defined for 32 and 64-bit environments
44 | #include // for _access(), _mktemp()
45 | #define GP_MAX_TMP_FILES 27 // 27 temporary files it's Microsoft restriction
46 | #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
47 | //all UNIX-like OSs (Linux, *BSD, MacOSX, Solaris, ...)
48 | #include // for access(), mkstemp()
49 | #define GP_MAX_TMP_FILES 64
50 | #else
51 | #error unsupported or unknown operating system
52 | #endif
53 |
54 | //declare classes in global namespace
55 |
56 |
57 | class GnuplotException : public std::runtime_error
58 | {
59 | public:
60 | explicit GnuplotException(const std::string &msg) : std::runtime_error(msg) {}
61 | };
62 |
63 |
64 |
65 | class Gnuplot
66 | {
67 | //----------------------------------------------------------------------------------
68 | // member data
69 | ///\brief pointer to the stream that can be used to write to the pipe
70 | FILE *gnucmd;
71 | ///\brief validation of gnuplot session
72 | bool valid;
73 | ///\brief true = 2d, false = 3d
74 | bool two_dim;
75 | ///\brief number of plots in session
76 | int nplots;
77 | ///\brief functions and data are displayed in a defined styles
78 | std::string pstyle;
79 | ///\brief interpolate and approximate data in defined styles (e.g. spline)
80 | std::string smooth;
81 | ///\brief list of created tmpfiles
82 | std::vector tmpfile_list;
83 |
84 | //----------------------------------------------------------------------------------
85 | // static data
86 | ///\brief number of all tmpfiles (number of tmpfiles restricted)
87 | static int tmpfile_num;
88 | ///\brief name of executed GNUPlot file
89 | static std::string m_sGNUPlotFileName;
90 | ///\brief gnuplot path
91 | static std::string m_sGNUPlotPath;
92 | ///\brief standard terminal, used by showonscreen
93 | static std::string terminal_std;
94 |
95 | //----------------------------------------------------------------------------------
96 | // member functions (auxiliary functions)
97 | // ---------------------------------------------------
98 | ///\brief get_program_path(); and popen();
99 | // ---------------------------------------------------
100 | void init(void);
101 | // ---------------------------------------------------
102 | ///\brief creates tmpfile and returns its name
103 | ///
104 | /// \param tmp points to the tempfile
105 | ///
106 | /// \return the name of the tempfile
107 | // ---------------------------------------------------
108 | std::string create_tmpfile(std::ofstream &tmp);
109 |
110 | //----------------------------------------------------------------------------------
111 | ///\brief gnuplot path found?
112 | ///
113 | /// \return found the gnuplot path (yes == true, no == false)
114 | // ---------------------------------------------------------------------------------
115 | static bool get_program_path(void);
116 |
117 | // ---------------------------------------------------------------------------------
118 | ///\brief checks if file is available
119 | ///
120 | /// \param filename the filename
121 | ///
122 | /// \return file exists (yes == true, no == false)
123 | // ---------------------------------------------------------------------------------
124 | static bool file_available(const std::string &filename);
125 |
126 | // ---------------------------------------------------------------------------------
127 | ///\brief checks if file exists
128 | ///
129 | /// \param filename the filename
130 | /// \param mode the mode [optional,default value = 0]
131 | ///
132 | /// \return file exists (yes == true, no == false)
133 | // ---------------------------------------------------------------------------------
134 | static bool file_exists(const std::string &filename, int mode = 0);
135 |
136 | public:
137 |
138 | // ----------------------------------------------------------------------------
139 | /// \brief optional function: set Gnuplot path manual
140 | /// attention: for windows: path with slash '/' not backslash '\'
141 | ///
142 | /// \param path the gnuplot path
143 | ///
144 | /// \return true on success, false otherwise
145 | // ----------------------------------------------------------------------------
146 | static bool set_GNUPlotPath(const std::string &path);
147 |
148 |
149 | // ----------------------------------------------------------------------------
150 | /// optional: set standard terminal, used by showonscreen
151 | /// defaults: Windows - win, Linux - x11, Mac - aqua
152 | ///
153 | /// \param type the terminal type
154 | // ----------------------------------------------------------------------------
155 | static void set_terminal_std(const std::string &type);
156 |
157 | //-----------------------------------------------------------------------------
158 | // constructors
159 | // ----------------------------------------------------------------------------
160 |
161 |
162 | ///\brief set a style during construction
163 | explicit Gnuplot(const std::string &style = "points");
164 |
165 | /// plot a single std::vector at one go
166 | explicit Gnuplot(const std::vector &x,
167 | const std::string &title = "",
168 | const std::string &style = "points",
169 | const std::string &labelx = "x",
170 | const std::string &labely = "y");
171 |
172 | /// plot pairs std::vector at one go
173 | explicit Gnuplot(const std::vector &x,
174 | const std::vector &y,
175 | const std::string &title = "",
176 | const std::string &style = "points",
177 | const std::string &labelx = "x",
178 | const std::string &labely = "y");
179 |
180 | /// plot triples std::vector at one go
181 | explicit Gnuplot(const std::vector &x,
182 | const std::vector &y,
183 | const std::vector &z,
184 | const std::string &title = "",
185 | const std::string &style = "points",
186 | const std::string &labelx = "x",
187 | const std::string &labely = "y",
188 | const std::string &labelz = "z");
189 |
190 | /// destructor: needed to delete temporary files
191 | ~Gnuplot(void);
192 |
193 |
194 | //----------------------------------------------------------------------------------
195 |
196 | /// send a command to gnuplot
197 | Gnuplot& cmd(const std::string &cmdstr);
198 | // -------------------------------------------------------------------------
199 | ///\brief Sends a command to an active gnuplot session, identical to cmd()
200 | /// send a command to gnuplot using the << operator
201 | ///
202 | /// \param cmdstr the command string
203 | ///
204 | /// \return a reference to the gnuplot object
205 | // -------------------------------------------------------------------------
206 | inline Gnuplot& operator<<(const std::string &cmdstr)
207 | {
208 | return cmd(cmdstr);
209 | }
210 |
211 |
212 |
213 | //--------------------------------------------------------------------------
214 | // show on screen or write to file
215 |
216 | /// sets terminal type to terminal_std
217 | Gnuplot& showonscreen(void); // window output is set by default (win/x11/aqua)
218 |
219 | /// Saves a gnuplot to a file named filename. Defaults to saving pdf
220 | Gnuplot& savetofigure(const std::string &filename,
221 | const std::string &terminal = "ps");
222 |
223 | //--------------------------------------------------------------------------
224 | // set and unset
225 |
226 | /// set line style (some of these styles require additional information):
227 | /// lines, points, linespoints, impulses, dots, steps, fsteps, histeps,
228 | /// boxes, histograms, filledcurves
229 | Gnuplot& set_style(const std::string &stylestr = "points");
230 |
231 | /// interpolation and approximation of data, arguments:
232 | /// csplines, bezier, acsplines (for data values > 0), sbezier, unique, frequency
233 | /// (works only with plot_x, plot_xy, plotfile_x, plotfile_xy
234 | /// (if smooth is set, set_style has no effect on data plotting)
235 | Gnuplot& set_smooth(const std::string &stylestr = "csplines");
236 |
237 | // ----------------------------------------------------------------------
238 | /// \brief unset smooth
239 | /// attention: smooth is not set by default
240 | ///
241 | /// \return a reference to a gnuplot object
242 | // ----------------------------------------------------------------------
243 | inline Gnuplot& unset_smooth(void)
244 | {
245 | smooth.clear();
246 | return *this;
247 | }
248 |
249 | /// scales the size of the points used in plots
250 | Gnuplot& set_pointsize(const double pointsize = 1.0);
251 |
252 | /// turns grid on/off
253 | inline Gnuplot& set_grid(void)
254 | {
255 | return cmd("set grid");
256 | }
257 | /// grid is not set by default
258 | inline Gnuplot& unset_grid(void)
259 | {
260 | return cmd("unset grid");
261 | }
262 |
263 | // -----------------------------------------------
264 | /// set the multiplot mode
265 | ///
266 | /// \return reference to the gnuplot object
267 | // -----------------------------------------------
268 | inline Gnuplot& set_multiplot(void)
269 | {
270 | return cmd("set multiplot");
271 | }
272 |
273 | // -----------------------------------------------
274 | /// unsets the multiplot mode
275 | ///
276 | /// \return reference to the gnuplot object
277 | // -----------------------------------------------
278 | inline Gnuplot& unset_multiplot(void)
279 | {
280 | return cmd("unset multiplot");
281 | }
282 |
283 | /// set sampling rate of functions, or for interpolating data
284 | Gnuplot& set_samples(const int samples = 100);
285 | /// set isoline density (grid) for plotting functions as surfaces (for 3d plots)
286 | Gnuplot& set_isosamples(const int isolines = 10);
287 |
288 | // --------------------------------------------------------------------------
289 | /// enables/disables hidden line removal for surface plotting (for 3d plot)
290 | ///
291 | /// \return reference to the gnuplot object
292 | // --------------------------------------------------------------------------
293 | Gnuplot& set_hidden3d(void)
294 | {
295 | return cmd("set hidden3d");
296 | }
297 |
298 | // ---------------------------------------------------------------------------
299 | /// hidden3d is not set by default
300 | ///
301 | /// \return reference to the gnuplot object
302 | // ---------------------------------------------------------------------------
303 | inline Gnuplot& unset_hidden3d(void)
304 | {
305 | return cmd("unset hidden3d");
306 | }
307 |
308 | /// enables/disables contour drawing for surfaces (for 3d plot)
309 | /// base, surface, both
310 | Gnuplot& set_contour(const std::string &position = "base");
311 | // --------------------------------------------------------------------------
312 | /// contour is not set by default, it disables contour drawing for surfaces
313 | ///
314 | /// \return reference to the gnuplot object
315 | // ------------------------------------------------------------------
316 | inline Gnuplot& unset_contour(void)
317 | {
318 | return cmd("unset contour");
319 | }
320 |
321 | // ------------------------------------------------------------
322 | /// enables/disables the display of surfaces (for 3d plot)
323 | ///
324 | /// \return reference to the gnuplot object
325 | // ------------------------------------------------------------------
326 | inline Gnuplot& set_surface(void)
327 | {
328 | return cmd("set surface");
329 | }
330 |
331 | // ----------------------------------------------------------
332 | /// surface is set by default,
333 | /// it disables the display of surfaces (for 3d plot)
334 | ///
335 | /// \return reference to the gnuplot object
336 | // ------------------------------------------------------------------
337 | inline Gnuplot& unset_surface(void)
338 | {
339 | return cmd("unset surface");
340 | }
341 |
342 |
343 | /// switches legend on/off
344 | /// position: inside/outside, left/center/right, top/center/bottom, nobox/box
345 | Gnuplot& set_legend(const std::string &position = "default");
346 |
347 | // ------------------------------------------------------------------
348 | /// \brief Switches legend off
349 | /// attention:legend is set by default
350 | ///
351 | /// \return reference to the gnuplot object
352 | // ------------------------------------------------------------------
353 | inline Gnuplot& unset_legend(void)
354 | {
355 | return cmd("unset key");
356 | }
357 |
358 | // -----------------------------------------------------------------------
359 | /// \brief sets and clears the title of a gnuplot session
360 | ///
361 | /// \param title the title of the plot [optional, default == ""]
362 | ///
363 | /// \return reference to the gnuplot object
364 | // -----------------------------------------------------------------------
365 | inline Gnuplot& set_title(const std::string &title = "")
366 | {
367 | const std::string cmdstr("set title \"" + title + "\"");
368 | *this << cmdstr;
369 | return *this;
370 | }
371 |
372 | //----------------------------------------------------------------------------------
373 | ///\brief Clears the title of a gnuplot session
374 | /// The title is not set by default.
375 | ///
376 | /// \return reference to the gnuplot object
377 | // ---------------------------------------------------------------------------------
378 | inline Gnuplot& unset_title(void)
379 | {
380 | return this->set_title();
381 | }
382 |
383 |
384 | /// set x axis label
385 | Gnuplot& set_ylabel(const std::string &label = "x");
386 | /// set y axis label
387 | Gnuplot& set_xlabel(const std::string &label = "y");
388 | /// set z axis label
389 | Gnuplot& set_zlabel(const std::string &label = "z");
390 |
391 | /// set axis - ranges
392 | Gnuplot& set_xrange(const double iFrom,
393 | const double iTo);
394 | /// set y-axis - ranges
395 | Gnuplot& set_yrange(const double iFrom,
396 | const double iTo);
397 | /// set z-axis - ranges
398 | Gnuplot& set_zrange(const double iFrom,
399 | const double iTo);
400 | /// autoscale axis (set by default) of xaxis
401 | ///
402 | /// \return reference to the gnuplot object
403 | // -----------------------------------------------
404 | inline Gnuplot& set_xautoscale(void)
405 | {
406 | (void)cmd("set xrange restore");
407 | return cmd("set autoscale x");
408 | }
409 |
410 | // -----------------------------------------------
411 | /// autoscale axis (set by default) of yaxis
412 | ///
413 | /// \return reference to the gnuplot object
414 | // -----------------------------------------------
415 | inline Gnuplot& set_yautoscale(void)
416 | {
417 | (void)cmd("set yrange restore");
418 | return cmd("set autoscale y");
419 | }
420 |
421 | // -----------------------------------------------
422 | /// autoscale axis (set by default) of zaxis
423 | ///
424 | /// \return reference to the gnuplot object
425 | // -----------------------------------------------
426 | inline Gnuplot& set_zautoscale(void)
427 | {
428 | (void)cmd("set zrange restore");
429 | return cmd("set autoscale z");
430 | }
431 |
432 |
433 | /// turns on/off log scaling for the specified xaxis (logscale is not set by default)
434 | Gnuplot& set_xlogscale(const double base = 10);
435 | /// turns on/off log scaling for the specified yaxis (logscale is not set by default)
436 | Gnuplot& set_ylogscale(const double base = 10);
437 | /// turns on/off log scaling for the specified zaxis (logscale is not set by default)
438 | Gnuplot& set_zlogscale(const double base = 10);
439 |
440 | // -----------------------------------------------
441 | /// turns off log scaling for the x axis
442 | ///
443 | /// \return reference to the gnuplot object
444 | // -----------------------------------------------
445 | inline Gnuplot& unset_xlogscale(void)
446 | {
447 | return cmd("unset logscale x");
448 | }
449 |
450 | // -----------------------------------------------
451 | /// turns off log scaling for the y axis
452 | ///
453 | /// \return reference to the gnuplot object
454 | // -----------------------------------------------
455 | inline Gnuplot& unset_ylogscale(void)
456 | {
457 | return cmd("unset logscale y");
458 | }
459 |
460 | // -----------------------------------------------
461 | /// turns off log scaling for the z axis
462 | ///
463 | /// \return reference to the gnuplot object
464 | // -----------------------------------------------
465 | inline Gnuplot& unset_zlogscale(void)
466 | {
467 | return cmd("unset logscale z");
468 | }
469 |
470 | /// set palette range (autoscale by default)
471 | Gnuplot& set_cbrange(const double iFrom, const double iTo);
472 |
473 |
474 | //--------------------------------------------------------------------------
475 | // plot
476 |
477 | /// plot a single std::vector: x
478 | /// from file
479 | Gnuplot& plotfile_x(const std::string &filename,
480 | const unsigned int column = 1,
481 | const std::string &title = "");
482 | /// from std::vector
483 | template
484 | Gnuplot& plot_x(const X& x, const std::string &title = "");
485 |
486 |
487 | /// plot x,y pairs: x y
488 | /// from file
489 | Gnuplot& plotfile_xy(const std::string &filename,
490 | const unsigned int column_x = 1,
491 | const unsigned int column_y = 2,
492 | const std::string &title = "");
493 | /// from data
494 | template
495 | Gnuplot& plot_xy(const X& x, const Y& y, const std::string &title = "");
496 |
497 |
498 | /// plot x,y pairs with dy errorbars: x y dy
499 | /// from file
500 | Gnuplot& plotfile_xy_err(const std::string &filename,
501 | const unsigned int column_x = 1,
502 | const unsigned int column_y = 2,
503 | const unsigned int column_dy = 3,
504 | const std::string &title = "");
505 | /// from data
506 | template
507 | Gnuplot& plot_xy_err(const X &x, const Y &y, const E &dy,
508 | const std::string &title = "");
509 |
510 |
511 | /// plot x,y,z triples: x y z
512 | /// from file
513 | Gnuplot& plotfile_xyz(const std::string &filename,
514 | const unsigned int column_x = 1,
515 | const unsigned int column_y = 2,
516 | const unsigned int column_z = 3,
517 | const std::string &title = "");
518 | /// from std::vector
519 | template
520 | Gnuplot& plot_xyz(const X &x,
521 | const Y &y,
522 | const Z &z,
523 | const std::string &title = "");
524 |
525 |
526 |
527 | /// plot an equation of the form: y = ax + b, you supply a and b
528 | Gnuplot& plot_slope(const double a,
529 | const double b,
530 | const std::string &title = "");
531 |
532 |
533 | /// plot an equation supplied as a std::string y=f(x), write only the
534 | /// function f(x) not y the independent variable has to be x
535 | /// binary operators: ** exponentiation, * multiply, / divide, + add, -
536 | /// subtract, % modulo
537 | /// unary operators: - minus, ! factorial
538 | /// elementary functions: rand(x), abs(x), sgn(x), ceil(x), floor(x),
539 | /// int(x), imag(x), real(x), arg(x), sqrt(x), exp(x), log(x), log10(x),
540 | /// sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x),
541 | /// sinh(x), cosh(x), tanh(x), asinh(x), acosh(x), atanh(x)
542 | /// special functions: erf(x), erfc(x), inverf(x), gamma(x), igamma(a,x),
543 | /// lgamma(x), ibeta(p,q,x), besj0(x), besj1(x), besy0(x), besy1(x),
544 | /// lambertw(x)
545 | /// statistical functions: norm(x), invnorm(x)
546 | Gnuplot& plot_equation(const std::string &equation,
547 | const std::string &title = "");
548 |
549 | /// plot an equation supplied as a std::string z=f(x,y), write only the
550 | /// function f(x,y) not z the independent variables have to be x and y
551 | Gnuplot& plot_equation3d(const std::string &equation,
552 | const std::string &title = "");
553 |
554 |
555 | /// plot image
556 | Gnuplot& plot_image(const unsigned char *ucPicBuf,
557 | const unsigned int iWidth,
558 | const unsigned int iHeight,
559 | const std::string &title = "");
560 |
561 |
562 | //--------------------------------------------------------------------------
563 | ///\brief replot repeats the last plot or splot command.
564 | /// this can be useful for viewing a plot with different set options,
565 | /// or when generating the same plot for several devices (showonscreen,
566 | /// savetofigure)
567 | ///
568 | /// \return ---
569 | //--------------------------------------------------------------------------
570 | inline Gnuplot& replot(void)
571 | {
572 | if (nplots > 0)
573 | {
574 | return cmd("replot");
575 | }
576 | return *this;
577 | }
578 |
579 | /// resets a gnuplot session (next plot will erase previous ones)
580 | Gnuplot& reset_plot(void);
581 |
582 | /// resets a gnuplot session and sets all variables to default
583 | Gnuplot& reset_all(void);
584 |
585 | /// deletes temporary files
586 | void remove_tmpfiles(void);
587 |
588 | /// \brief Is the gnuplot session valid ??
589 | ///
590 | /// \return true if valid, false if not
591 | inline bool is_valid(void) const
592 | {
593 | return valid;
594 | }
595 | };
596 |
597 | //------------------------------------------------------------------------------
598 | //
599 | // initialize static data
600 | //
601 | int Gnuplot::tmpfile_num = 0;
602 |
603 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
604 | std::string Gnuplot::m_sGNUPlotFileName = "pgnuplot.exe";
605 | std::string Gnuplot::m_sGNUPlotPath = "C:/program files/gnuplot/bin/";
606 | #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
607 | std::string Gnuplot::m_sGNUPlotFileName = "gnuplot";
608 | std::string Gnuplot::m_sGNUPlotPath = "/usr/local/bin/";
609 | #endif
610 |
611 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
612 | std::string Gnuplot::terminal_std = "windows";
613 | #elif ( defined(unix) || defined(__unix) || defined(__unix__) ) && !defined(__APPLE__)
614 | std::string Gnuplot::terminal_std = "x11";
615 | #elif defined(__APPLE__)
616 | std::string Gnuplot::terminal_std = "aqua";
617 | #endif
618 |
619 | //------------------------------------------------------------------------------
620 | //
621 | // constructor: set a style during construction
622 | //
623 | inline Gnuplot::Gnuplot(const std::string &style)
624 | : gnucmd(nullptr) , valid(false) , two_dim(false) , nplots(0)
625 |
626 | {
627 | init();
628 | (void)set_style(style);
629 | }
630 |
631 | //------------------------------------------------------------------------------
632 | //
633 | // constructor: open a new session, plot a signal (x)
634 | //
635 | inline Gnuplot::Gnuplot(const std::vector &x,
636 | const std::string &title,
637 | const std::string &style,
638 | const std::string &labelx,
639 | const std::string &labely)
640 | : gnucmd(nullptr) , valid(false) , two_dim(false) , nplots(0)
641 | {
642 | init();
643 |
644 | (void)set_style(style);
645 | (void)set_xlabel(labelx);
646 | (void)set_ylabel(labely);
647 |
648 | (void)plot_x(x, title);
649 | }
650 |
651 |
652 | // constructor: open a new session, plot a signal (x,y)
653 | inline Gnuplot::Gnuplot(const std::vector &x,
654 | const std::vector &y,
655 | const std::string &title,
656 | const std::string &style,
657 | const std::string &labelx,
658 | const std::string &labely)
659 | : gnucmd(nullptr) , valid(false) , two_dim(false) , nplots(0)
660 | {
661 | init();
662 |
663 | (void)set_style(style);
664 | (void)set_xlabel(labelx);
665 | (void)set_ylabel(labely);
666 |
667 | (void)plot_xy(x, y, title);
668 | }
669 |
670 | // constructor: open a new session, plot a signal (x,y,z)
671 | inline Gnuplot::Gnuplot(const std::vector &x,
672 | const std::vector &y,
673 | const std::vector &z,
674 | const std::string &title,
675 | const std::string &style,
676 | const std::string &labelx,
677 | const std::string &labely,
678 | const std::string &labelz)
679 | : gnucmd(nullptr) , valid(false) , two_dim(false) , nplots(0)
680 | {
681 | init();
682 |
683 | (void)set_style(style);
684 | (void)set_xlabel(labelx);
685 | (void)set_ylabel(labely);
686 | (void)set_zlabel(labelz);
687 |
688 | (void)plot_xyz(x, y, z, title);
689 | }
690 |
691 | /// Plots a 2d graph from a list of doubles: x
692 | template
693 | Gnuplot& Gnuplot::plot_x(const X& x, const std::string &title)
694 | {
695 | if (x.empty())
696 | {
697 | throw GnuplotException("std::vector too small");
698 | }
699 |
700 | std::ofstream tmp;
701 | std::string name = create_tmpfile(tmp);
702 | if (name.empty())
703 | {
704 | return *this;
705 | }
706 |
707 | //
708 | // write the data to file
709 | //
710 | for (unsigned int i = 0; i < x.size(); ++i)
711 | {
712 | tmp << x[i] << std::endl;
713 | }
714 |
715 | tmp.flush();
716 | tmp.close();
717 |
718 |
719 | plotfile_x(name, 1, title);
720 |
721 | return *this;
722 | }
723 |
724 |
725 | /// Plots a 2d graph from a list of doubles: x y
726 | template
727 | Gnuplot& Gnuplot::plot_xy(const X& x, const Y& y, const std::string &title)
728 | {
729 | if (x.empty() || y.empty())
730 | {
731 | throw GnuplotException("std::vectors too small");
732 | }
733 |
734 | if (x.size() != y.size())
735 | {
736 | throw GnuplotException("Length of the std::vectors differs");
737 | }
738 | std::ofstream tmp;
739 | const std::string name = create_tmpfile(tmp);
740 | if (name.empty())
741 | {
742 | throw GnuplotException("Unable to create tmp-file.");
743 | }
744 | // write the data to file
745 | for (std::size_t i = 0; i < x.size(); ++i)
746 | {
747 | tmp << x[i] << " " << y[i] << std::endl;
748 | }
749 | // Cleanup
750 | tmp.flush();
751 | tmp.close();
752 | // Plot
753 | plotfile_xy(name, 1, 2, title);
754 |
755 | return *this;
756 | }
757 |
758 | /// Plot x,y pairs with dy errorbars
759 | template
760 | Gnuplot& Gnuplot::plot_xy_err(const X &x,
761 | const Y &y,
762 | const E &dy,
763 | const std::string &title)
764 | {
765 | if (x.empty() || y.empty() || dy.empty())
766 | {
767 | throw GnuplotException("std::vectors too small");
768 | }
769 |
770 | if (x.size() != y.size() || y.size() != dy.size())
771 | {
772 | throw GnuplotException("Length of the std::vectors differs");
773 | }
774 | std::ofstream tmp;
775 | const std::string name = create_tmpfile(tmp);
776 | if (name.empty())
777 | {
778 | throw GnuplotException("Unable to create tmp-file.");
779 | }
780 | // write the data to file
781 | for (std::size_t i = 0; i < x.size(); ++i)
782 | {
783 | tmp << x[i] << " " << y[i] << " " << dy[i] << std::endl;
784 | }
785 | // Cleanup
786 | tmp.flush();
787 | tmp.close();
788 | // Do the actual plot
789 | plotfile_xy_err(name, 1, 2, 3, title);
790 |
791 | return *this;
792 | }
793 |
794 | /// Plots a 3d graph from a list of doubles: x y z
795 | template
796 | Gnuplot& Gnuplot::plot_xyz(const X &x,
797 | const Y &y,
798 | const Z &z,
799 | const std::string &title)
800 | {
801 | if (x.empty() || y.empty() || z.empty())
802 | {
803 | throw GnuplotException("std::vectors too small");
804 | }
805 | if (x.size() != y.size() || x.size() != z.size())
806 | {
807 | throw GnuplotException("Length of the std::vectors differs");
808 | }
809 | std::ofstream tmp;
810 | const std::string name = create_tmpfile(tmp);
811 | if (name.empty())
812 | {
813 | throw GnuplotException("Unable to create tmp-file.");
814 | }
815 | // write the data to file
816 | for (std::size_t i = 0; i < x.size(); ++i)
817 | {
818 | tmp << x[i] << " " << y[i] << " " << z[i] << std::endl;
819 | }
820 | // cleanup
821 | tmp.flush();
822 | tmp.close();
823 | // plot file
824 | plotfile_xyz(name, 1, 2, 3, title);
825 |
826 | return *this;
827 | }
828 |
829 | // define static member function: set Gnuplot path manual
830 | // for windows: path with slash '/' not backslash '\'
831 | //
832 | bool Gnuplot::set_GNUPlotPath(const std::string &path)
833 | {
834 | const std::string tmp = path + "/" + Gnuplot::m_sGNUPlotFileName;
835 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
836 | if ( Gnuplot::file_exists(tmp, 0) ) // check existence
837 | #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
838 | if ( Gnuplot::file_exists(tmp, 1) ) // check existence and execution permission
839 | #endif
840 | {
841 | Gnuplot::m_sGNUPlotPath = path;
842 | return true;
843 | }
844 | Gnuplot::m_sGNUPlotPath.clear();
845 | return false;
846 | }
847 |
848 | //------------------------------------------------------------------------------
849 | //
850 | // define static member function: set default terminal, used by showonscreen
851 | // defaults: Windows - win, Linux - x11, Mac - aqua
852 | //
853 | void Gnuplot::set_terminal_std(const std::string &type)
854 | {
855 | #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
856 | if (type.find("x11") != std::string::npos && getenv("DISPLAY") == nullptr)
857 | {
858 | throw GnuplotException("Can't find DISPLAY variable");
859 | }
860 | #endif
861 | Gnuplot::terminal_std = type;
862 | }
863 |
864 |
865 | //------------------------------------------------------------------------------
866 | //
867 | // A string tokenizer taken from http://www.sunsite.ualberta.ca/Documentation/
868 | // /Gnu/libstdc++-2.90.8/html/21_strings/stringtok_std_h.txt
869 | //
870 | template
871 | void stringtok (Container &container,
872 | std::string const &in,
873 | const char * const delimiters = " \t\n")
874 | {
875 | const std::string::size_type len = in.length();
876 | std::string::size_type i = 0;
877 |
878 | while ( i < len )
879 | {
880 | // eat leading whitespace
881 | i = in.find_first_not_of (delimiters, i);
882 |
883 | if (i == std::string::npos)
884 | {
885 | return; // nothing left but white space
886 | }
887 |
888 | // find the end of the token
889 | const std::string::size_type j = in.find_first_of (delimiters, i);
890 |
891 | // push token
892 | if (j == std::string::npos)
893 | {
894 | container.push_back (in.substr(i));
895 | return;
896 | }
897 | container.push_back (in.substr(i, j - i));
898 |
899 | // set up for next loop
900 | i = j + 1;
901 | }
902 |
903 | return;
904 | }
905 |
906 |
907 | //------------------------------------------------------------------------------
908 | //
909 | // Destructor: needed to delete temporary files
910 | //
911 | Gnuplot::~Gnuplot(void)
912 | {
913 | // remove_tmpfiles();
914 |
915 | // A stream opened by popen() should be closed by pclose()
916 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
917 | if (_pclose(gnucmd) == -1)
918 | #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
919 | if (pclose(gnucmd) == -1)
920 | #endif
921 | { std::cerr << "Gnuplot::~Gnuplot: Problem closing communication to gnuplot" << std::endl; }
922 | }
923 |
924 |
925 | //------------------------------------------------------------------------------
926 | //
927 | // Resets a gnuplot session (next plot will erase previous ones)
928 | //
929 | Gnuplot& Gnuplot::reset_plot(void)
930 | {
931 | // remove_tmpfiles();
932 |
933 | nplots = 0;
934 |
935 | return *this;
936 | }
937 |
938 |
939 | //------------------------------------------------------------------------------
940 | //
941 | // resets a gnuplot session and sets all variables to default
942 | //
943 | Gnuplot& Gnuplot::reset_all(void)
944 | {
945 | // remove_tmpfiles();
946 |
947 | nplots = 0;
948 | (void)cmd("reset");
949 | (void)cmd("clear");
950 | pstyle = "points";
951 | smooth.clear();
952 | showonscreen();
953 |
954 | return *this;
955 | }
956 |
957 |
958 | //------------------------------------------------------------------------------
959 | //
960 | // Change the plotting style of a gnuplot session
961 | //
962 | Gnuplot& Gnuplot::set_style(const std::string &stylestr)
963 | {
964 | if( (pstyle != stylestr) && !stylestr.empty() )
965 | {
966 | pstyle = stylestr;
967 | }
968 | return *this;
969 | }
970 |
971 |
972 | //------------------------------------------------------------------------------
973 | //
974 | // smooth: interpolation and approximation of data
975 | //
976 | Gnuplot& Gnuplot::set_smooth(const std::string &stylestr)
977 | {
978 | if (stylestr.find("unique") == std::string::npos &&
979 | stylestr.find("frequency") == std::string::npos &&
980 | stylestr.find("csplines") == std::string::npos &&
981 | stylestr.find("bezier") == std::string::npos )
982 | {
983 | smooth.clear();
984 | }
985 | else
986 | {
987 | smooth = stylestr;
988 | }
989 |
990 | return *this;
991 | }
992 |
993 |
994 | //------------------------------------------------------------------------------
995 | //
996 | // sets terminal type to windows / x11
997 | //
998 | Gnuplot& Gnuplot::showonscreen(void)
999 | {
1000 | (void)cmd("set output");
1001 | return cmd("set terminal " + Gnuplot::terminal_std);
1002 | }
1003 |
1004 | //------------------------------------------------------------------------------
1005 | //
1006 | // saves a gnuplot session to a postscript file
1007 | //
1008 | Gnuplot& Gnuplot::savetofigure(const std::string &filename,
1009 | const std::string &terminal)
1010 | {
1011 | std::ostringstream cmdstr;
1012 | cmdstr << "set terminal " << terminal;
1013 | (void)cmd(cmdstr.str() );
1014 |
1015 | cmdstr.str(""); // Clear cmdstr
1016 | cmdstr << "set output \"" << filename << "\"";
1017 | return cmd(cmdstr.str());
1018 | }
1019 |
1020 | //------------------------------------------------------------------------------
1021 | //
1022 | // Switches legend on
1023 | //
1024 | Gnuplot& Gnuplot::set_legend(const std::string &position)
1025 | {
1026 | std::ostringstream cmdstr;
1027 | cmdstr << "set key " << position;
1028 |
1029 | return cmd(cmdstr.str());
1030 | }
1031 |
1032 | //------------------------------------------------------------------------------
1033 | //
1034 | // turns on log scaling for the x axis
1035 | //
1036 | Gnuplot& Gnuplot::set_xlogscale(const double base)
1037 | {
1038 | std::ostringstream cmdstr;
1039 |
1040 | cmdstr << "set logscale x " << base;
1041 | return cmd(cmdstr.str());
1042 | }
1043 |
1044 | //------------------------------------------------------------------------------
1045 | //
1046 | // turns on log scaling for the y axis
1047 | //
1048 | Gnuplot& Gnuplot::set_ylogscale(const double base)
1049 | {
1050 | std::ostringstream cmdstr;
1051 |
1052 | cmdstr << "set logscale y " << base;
1053 | return cmd(cmdstr.str());
1054 | }
1055 |
1056 | //------------------------------------------------------------------------------
1057 | //
1058 | // turns on log scaling for the z axis
1059 | //
1060 | Gnuplot& Gnuplot::set_zlogscale(const double base)
1061 | {
1062 | std::ostringstream cmdstr;
1063 |
1064 | cmdstr << "set logscale z " << base;
1065 | return cmd(cmdstr.str());
1066 | }
1067 |
1068 | //------------------------------------------------------------------------------
1069 | //
1070 | // scales the size of the points used in plots
1071 | //
1072 | Gnuplot& Gnuplot::set_pointsize(const double pointsize)
1073 | {
1074 | std::ostringstream cmdstr;
1075 |
1076 | cmdstr << "set pointsize " << pointsize;
1077 | return cmd(cmdstr.str());
1078 | }
1079 |
1080 | //------------------------------------------------------------------------------
1081 | //
1082 | // set isoline density (grid) for plotting functions as surfaces
1083 | //
1084 | Gnuplot& Gnuplot::set_samples(const int samples)
1085 | {
1086 | std::ostringstream cmdstr;
1087 | cmdstr << "set samples " << samples;
1088 | return cmd(cmdstr.str());
1089 | }
1090 |
1091 |
1092 | //------------------------------------------------------------------------------
1093 | //
1094 | // set isoline density (grid) for plotting functions as surfaces
1095 | //
1096 | Gnuplot& Gnuplot::set_isosamples(const int isolines)
1097 | {
1098 | std::ostringstream cmdstr;
1099 | cmdstr << "set isosamples " << isolines;
1100 | return cmd(cmdstr.str());
1101 | }
1102 |
1103 |
1104 | //------------------------------------------------------------------------------
1105 | //
1106 | // enables contour drawing for surfaces set contour {base | surface | both}
1107 | //
1108 |
1109 | Gnuplot& Gnuplot::set_contour(const std::string &position)
1110 | {
1111 | if (position.find("base") == std::string::npos &&
1112 | position.find("surface") == std::string::npos &&
1113 | position.find("both") == std::string::npos )
1114 | {
1115 | return cmd("set contour base");
1116 | }
1117 |
1118 | return cmd("set contour " + position);
1119 | }
1120 |
1121 | //------------------------------------------------------------------------------
1122 | //
1123 | // set labels
1124 | //
1125 | // set the xlabel
1126 | Gnuplot& Gnuplot::set_xlabel(const std::string &label)
1127 | {
1128 | std::ostringstream cmdstr;
1129 |
1130 | cmdstr << "set xlabel \"" << label << "\"";
1131 | return cmd(cmdstr.str());
1132 | }
1133 |
1134 | //------------------------------------------------------------------------------
1135 | // set the ylabel
1136 | //
1137 | Gnuplot& Gnuplot::set_ylabel(const std::string &label)
1138 | {
1139 | std::ostringstream cmdstr;
1140 |
1141 | cmdstr << "set ylabel \"" << label << "\"";
1142 | return cmd(cmdstr.str());
1143 | }
1144 |
1145 | //------------------------------------------------------------------------------
1146 | // set the zlabel
1147 | //
1148 | Gnuplot& Gnuplot::set_zlabel(const std::string &label)
1149 | {
1150 | std::ostringstream cmdstr;
1151 |
1152 | cmdstr << "set zlabel \"" << label << "\"";
1153 | return cmd(cmdstr.str());
1154 | }
1155 |
1156 | //------------------------------------------------------------------------------
1157 | //
1158 | // set range
1159 | //
1160 | // set the xrange
1161 | Gnuplot& Gnuplot::set_xrange(const double iFrom,
1162 | const double iTo)
1163 | {
1164 | std::ostringstream cmdstr;
1165 |
1166 | cmdstr << "set xrange[" << iFrom << ":" << iTo << "]";
1167 | return cmd(cmdstr.str());
1168 | }
1169 |
1170 | //------------------------------------------------------------------------------
1171 | // set the yrange
1172 | //
1173 | Gnuplot& Gnuplot::set_yrange(const double iFrom,
1174 | const double iTo)
1175 | {
1176 | std::ostringstream cmdstr;
1177 |
1178 | cmdstr << "set yrange[" << iFrom << ":" << iTo << "]";
1179 | return cmd(cmdstr.str());
1180 | }
1181 |
1182 | //------------------------------------------------------------------------------
1183 | // set the zrange
1184 | //
1185 | Gnuplot& Gnuplot::set_zrange(const double iFrom,
1186 | const double iTo)
1187 | {
1188 | std::ostringstream cmdstr;
1189 |
1190 | cmdstr << "set zrange[" << iFrom << ":" << iTo << "]";
1191 | return cmd(cmdstr.str());
1192 | }
1193 |
1194 | //------------------------------------------------------------------------------
1195 | //
1196 | // set the palette range
1197 | //
1198 | Gnuplot& Gnuplot::set_cbrange(const double iFrom,
1199 | const double iTo)
1200 | {
1201 | std::ostringstream cmdstr;
1202 |
1203 | cmdstr << "set cbrange[" << iFrom << ":" << iTo << "]";
1204 | return cmd(cmdstr.str());
1205 | }
1206 |
1207 | //------------------------------------------------------------------------------
1208 | //
1209 | // Plots a linear equation y=ax+b (where you supply the
1210 | // slope a and intercept b)
1211 | //
1212 | Gnuplot& Gnuplot::plot_slope(const double a,
1213 | const double b,
1214 | const std::string &title)
1215 | {
1216 | std::ostringstream cmdstr;
1217 | //
1218 | // command to be sent to gnuplot
1219 | //
1220 | if (nplots > 0 && two_dim == true)
1221 | {
1222 | cmdstr << "replot ";
1223 | }
1224 | else
1225 | {
1226 | cmdstr << "plot ";
1227 | }
1228 |
1229 | cmdstr << a << " * x + " << b << " title \"";
1230 |
1231 | if (title.empty())
1232 | {
1233 | cmdstr << "f(x) = " << a << " * x + " << b;
1234 | }
1235 | else
1236 | {
1237 | cmdstr << title;
1238 | }
1239 |
1240 | cmdstr << "\" with " << pstyle;
1241 |
1242 | //
1243 | // Do the actual plot
1244 | //
1245 | return cmd(cmdstr.str());
1246 | }
1247 |
1248 | //------------------------------------------------------------------------------
1249 | //
1250 | // Plot an equation supplied as a std::string y=f(x) (only f(x) expected)
1251 | //
1252 | Gnuplot& Gnuplot::plot_equation(const std::string &equation,
1253 | const std::string &title)
1254 | {
1255 | std::ostringstream cmdstr;
1256 | //
1257 | // command to be sent to gnuplot
1258 | //
1259 | if (nplots > 0 && two_dim == true)
1260 | {
1261 | cmdstr << "replot ";
1262 | }
1263 | else
1264 | {
1265 | cmdstr << "plot ";
1266 | }
1267 |
1268 | cmdstr << equation;
1269 |
1270 | if (title.empty())
1271 | {
1272 | cmdstr << " notitle";
1273 | }
1274 | else
1275 | {
1276 | cmdstr << " title \"" << title << "\"";
1277 | }
1278 |
1279 | cmdstr << " with " << pstyle;
1280 |
1281 | //
1282 | // Do the actual plot
1283 | //
1284 | return cmd(cmdstr.str());
1285 | }
1286 |
1287 | //------------------------------------------------------------------------------
1288 | //
1289 | // plot an equation supplied as a std::string y=(x)
1290 | //
1291 | Gnuplot& Gnuplot::plot_equation3d(const std::string &equation,
1292 | const std::string &title)
1293 | {
1294 | std::ostringstream cmdstr;
1295 | //
1296 | // command to be sent to gnuplot
1297 | //
1298 | if (nplots > 0 && two_dim == false)
1299 | {
1300 | cmdstr << "replot ";
1301 | }
1302 | else
1303 | {
1304 | cmdstr << "splot ";
1305 | }
1306 |
1307 | cmdstr << equation << " title \"";
1308 |
1309 | if (title.empty())
1310 | {
1311 | cmdstr << "f(x,y) = " << equation;
1312 | }
1313 | else
1314 | {
1315 | cmdstr << title;
1316 | }
1317 |
1318 | cmdstr << "\" with " << pstyle;
1319 |
1320 | //
1321 | // Do the actual plot
1322 | //
1323 | return cmd(cmdstr.str());
1324 | }
1325 |
1326 |
1327 | //------------------------------------------------------------------------------
1328 | //
1329 | // Plots a 2d graph from a list of doubles (x) saved in a file
1330 | //
1331 | Gnuplot& Gnuplot::plotfile_x(const std::string &filename,
1332 | const unsigned int column,
1333 | const std::string &title)
1334 | {
1335 | //
1336 | // check if file exists
1337 | //
1338 | file_available(filename);
1339 |
1340 | std::ostringstream cmdstr;
1341 | //
1342 | // command to be sent to gnuplot
1343 | //
1344 | if (nplots > 0 && two_dim == true)
1345 | {
1346 | cmdstr << "replot ";
1347 | }
1348 | else
1349 | {
1350 | cmdstr << "plot ";
1351 | }
1352 |
1353 | cmdstr << "\"" << filename << "\" using " << column;
1354 |
1355 | if (title.empty())
1356 | {
1357 | cmdstr << " notitle ";
1358 | }
1359 | else
1360 | {
1361 | cmdstr << " title \"" << title << "\" ";
1362 | }
1363 |
1364 | if(smooth.empty())
1365 | {
1366 | cmdstr << "with " << pstyle;
1367 | }
1368 | else
1369 | {
1370 | cmdstr << "smooth " << smooth;
1371 | }
1372 |
1373 | //
1374 | // Do the actual plot
1375 | //
1376 | return cmd(cmdstr.str()); //nplots++; two_dim = true; already in cmd();
1377 | }
1378 |
1379 |
1380 |
1381 | //------------------------------------------------------------------------------
1382 | //
1383 | // Plots a 2d graph from a list of doubles (x y) saved in a file
1384 | //
1385 | Gnuplot& Gnuplot::plotfile_xy(const std::string &filename,
1386 | const unsigned int column_x,
1387 | const unsigned int column_y,
1388 | const std::string &title)
1389 | {
1390 | //
1391 | // check if file exists
1392 | //
1393 | file_available(filename);
1394 |
1395 | std::ostringstream cmdstr;
1396 | //
1397 | // command to be sent to gnuplot
1398 | //
1399 | if (nplots > 0 && two_dim == true)
1400 | {
1401 | cmdstr << "replot ";
1402 | }
1403 | else
1404 | {
1405 | cmdstr << "plot ";
1406 | }
1407 |
1408 | cmdstr << "\"" << filename << "\" using " << column_x << ":" << column_y;
1409 |
1410 | if (title.empty())
1411 | {
1412 | cmdstr << " notitle ";
1413 | }
1414 | else
1415 | {
1416 | cmdstr << " title \"" << title << "\" ";
1417 | }
1418 |
1419 | if(smooth.empty())
1420 | {
1421 | cmdstr << "with " << pstyle;
1422 | }
1423 | else
1424 | {
1425 | cmdstr << "smooth " << smooth;
1426 | }
1427 |
1428 | //
1429 | // Do the actual plot
1430 | //
1431 | return cmd(cmdstr.str());
1432 | }
1433 |
1434 |
1435 | //------------------------------------------------------------------------------
1436 | //
1437 | // Plots a 2d graph with errorbars from a list of doubles (x y dy) in a file
1438 | //
1439 | Gnuplot& Gnuplot::plotfile_xy_err(const std::string &filename,
1440 | const unsigned int column_x,
1441 | const unsigned int column_y,
1442 | const unsigned int column_dy,
1443 | const std::string &title)
1444 | {
1445 | //
1446 | // check if file exists
1447 | //
1448 | file_available(filename);
1449 |
1450 | std::ostringstream cmdstr;
1451 | //
1452 | // command to be sent to gnuplot
1453 | //
1454 | if (nplots > 0 && two_dim == true)
1455 | {
1456 | cmdstr << "replot ";
1457 | }
1458 | else
1459 | {
1460 | cmdstr << "plot ";
1461 | }
1462 |
1463 | cmdstr << "\"" << filename << "\" using "
1464 | << column_x << ":" << column_y << ":" << column_dy
1465 | << " with errorbars ";
1466 |
1467 | if (title.empty())
1468 | {
1469 | cmdstr << " notitle ";
1470 | }
1471 | else
1472 | {
1473 | cmdstr << " title \"" << title << "\" ";
1474 | }
1475 |
1476 | //
1477 | // Do the actual plot
1478 | //
1479 | return cmd(cmdstr.str());
1480 | }
1481 |
1482 |
1483 | //------------------------------------------------------------------------------
1484 | //
1485 | // Plots a 3d graph from a list of doubles (x y z) saved in a file
1486 | //
1487 | Gnuplot& Gnuplot::plotfile_xyz(const std::string &filename,
1488 | const unsigned int column_x,
1489 | const unsigned int column_y,
1490 | const unsigned int column_z,
1491 | const std::string &title)
1492 | {
1493 | //
1494 | // check if file exists
1495 | //
1496 | file_available(filename);
1497 |
1498 | std::ostringstream cmdstr;
1499 | //
1500 | // command to be sent to gnuplot
1501 | //
1502 | if (nplots > 0 && two_dim == false)
1503 | {
1504 | cmdstr << "replot ";
1505 | }
1506 | else
1507 | {
1508 | cmdstr << "splot ";
1509 | }
1510 |
1511 | cmdstr << "\"" << filename << "\" using " << column_x << ":" << column_y
1512 | << ":" << column_z;
1513 |
1514 | if (title.empty())
1515 | {
1516 | cmdstr << " notitle with " << pstyle;
1517 | }
1518 | else
1519 | {
1520 | cmdstr << " title \"" << title << "\" with " << pstyle;
1521 | }
1522 |
1523 | //
1524 | // Do the actual plot
1525 | //
1526 | return cmd(cmdstr.str());
1527 | }
1528 |
1529 |
1530 |
1531 | //------------------------------------------------------------------------------
1532 | //
1533 | /// * note that this function is not valid for versions of GNUPlot below 4.2
1534 | //
1535 | Gnuplot& Gnuplot::plot_image(const unsigned char * ucPicBuf,
1536 | const unsigned int iWidth,
1537 | const unsigned int iHeight,
1538 | const std::string &title)
1539 | {
1540 | std::ofstream tmp;
1541 | std::string name = create_tmpfile(tmp);
1542 | if (name.empty())
1543 | {
1544 | return *this;
1545 | }
1546 |
1547 | //
1548 | // write the data to file
1549 | //
1550 | int iIndex = 0;
1551 | for(unsigned int iRow = 0; iRow < iHeight; ++iRow)
1552 | {
1553 | for(unsigned int iColumn = 0; iColumn < iWidth; ++iColumn)
1554 | {
1555 | tmp << iColumn << " " << iRow << " "
1556 | << static_cast(ucPicBuf[iIndex++]) << std::endl;
1557 | }
1558 | }
1559 |
1560 | tmp.flush();
1561 | tmp.close();
1562 |
1563 | std::ostringstream cmdstr;
1564 | //
1565 | // command to be sent to gnuplot
1566 | //
1567 | if (nplots > 0 && two_dim == true)
1568 | {
1569 | cmdstr << "replot ";
1570 | }
1571 | else
1572 | {
1573 | cmdstr << "plot ";
1574 | }
1575 |
1576 | if (title.empty())
1577 | {
1578 | cmdstr << "\"" << name << "\" with image";
1579 | }
1580 | else
1581 | {
1582 | cmdstr << "\"" << name << "\" title \"" << title << "\" with image";
1583 | }
1584 |
1585 | //
1586 | // Do the actual plot
1587 | //
1588 | return cmd(cmdstr.str());
1589 | }
1590 |
1591 |
1592 |
1593 | //------------------------------------------------------------------------------
1594 | //
1595 | // Sends a command to an active gnuplot session
1596 | //
1597 | Gnuplot& Gnuplot::cmd(const std::string &cmdstr)
1598 | {
1599 | if( !(valid) )
1600 | {
1601 | return *this;
1602 | }
1603 |
1604 |
1605 | // int fputs ( const char * str, FILE * stream );
1606 | // writes the string str to the stream.
1607 | // The function begins copying from the address specified (str) until it
1608 | // reaches the terminating null character ('\0'). This final
1609 | // null-character is not copied to the stream.
1610 | fputs( (cmdstr + "\n").c_str(), gnucmd );
1611 |
1612 | // int fflush ( FILE * stream );
1613 | // If the given stream was open for writing and the last i/o operation was
1614 | // an output operation, any unwritten data in the output buffer is written
1615 | // to the file. If the argument is a null pointer, all open files are
1616 | // flushed. The stream remains open after this call.
1617 | fflush(gnucmd);
1618 |
1619 | if( cmdstr.find("splot") != std::string::npos )
1620 | {
1621 | two_dim = false;
1622 | ++nplots;
1623 | return *this;
1624 | }
1625 | else if( cmdstr.find("plot") != std::string::npos )
1626 | {
1627 | two_dim = true;
1628 | ++nplots;
1629 | return *this;
1630 | }
1631 | else
1632 | {
1633 | return *this;
1634 | }
1635 | }
1636 |
1637 | //------------------------------------------------------------------------------
1638 | //
1639 | // Opens up a gnuplot session, ready to receive commands
1640 | //
1641 | void Gnuplot::init(void)
1642 | {
1643 | // char * getenv ( const char * name ); get value of environment variable
1644 | // Retrieves a C string containing the value of the environment variable
1645 | // whose name is specified as argument. If the requested variable is not
1646 | // part of the environment list, the function returns a NULL pointer.
1647 | #if ( defined(unix) || defined(__unix) || defined(__unix__) ) && !defined(__APPLE__)
1648 | if (getenv("DISPLAY") == nullptr)
1649 | {
1650 | valid = false;
1651 | throw GnuplotException("Can't find DISPLAY variable");
1652 | }
1653 | #endif
1654 |
1655 | // if gnuplot not available
1656 | if (!Gnuplot::get_program_path())
1657 | {
1658 | valid = false;
1659 | throw GnuplotException("Can't find gnuplot");
1660 | }
1661 |
1662 | // open pipe
1663 | std::string tmp = Gnuplot::m_sGNUPlotPath + "/" +
1664 | Gnuplot::m_sGNUPlotFileName;
1665 |
1666 | // FILE *popen(const char *command, const char *mode);
1667 | // The popen() function shall execute the command specified by the string
1668 | // command, create a pipe between the calling program and the executed
1669 | // command, and return a pointer to a stream that can be used to either read
1670 | // from or write to the pipe.
1671 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
1672 | gnucmd = _popen(tmp.c_str(), "w");
1673 | #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
1674 | gnucmd = popen(tmp.c_str(), "w");
1675 | #endif
1676 |
1677 | // popen() shall return a pointer to an open stream that can be used to read
1678 | // or write to the pipe. Otherwise, it shall return a null pointer and may
1679 | // set errno to indicate the error.
1680 | if (!gnucmd)
1681 | {
1682 | valid = false;
1683 | throw GnuplotException("Couldn't open connection to gnuplot");
1684 | }
1685 |
1686 | nplots = 0;
1687 | valid = true;
1688 | smooth.clear();
1689 |
1690 | //set terminal type
1691 | showonscreen();
1692 |
1693 | return;
1694 | }
1695 |
1696 |
1697 | //------------------------------------------------------------------------------
1698 | //
1699 | // Find out if a command lives in m_sGNUPlotPath or in PATH
1700 | //
1701 | bool Gnuplot::get_program_path(void)
1702 | {
1703 | //
1704 | // first look in m_sGNUPlotPath for Gnuplot
1705 | //
1706 | std::string tmp = Gnuplot::m_sGNUPlotPath + "/" +
1707 | Gnuplot::m_sGNUPlotFileName;
1708 |
1709 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
1710 | if ( Gnuplot::file_exists(tmp, 0) ) // check existence
1711 | #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
1712 | if ( Gnuplot::file_exists(tmp, 1) ) // check existence and execution permission
1713 | #endif
1714 | {
1715 | return true;
1716 | }
1717 |
1718 |
1719 | //
1720 | // second look in PATH for Gnuplot
1721 | // Retrieves a C string containing the value of environment variable PATH
1722 | const char * const path = getenv("PATH");
1723 |
1724 | if (path == nullptr)
1725 | {
1726 | throw GnuplotException("Path is not set");
1727 | }
1728 | std::list ls;
1729 |
1730 | //split path (one long string) into list ls of strings
1731 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
1732 | stringtok(ls, path, ";");
1733 | #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
1734 | stringtok(ls, path, ":");
1735 | #endif
1736 |
1737 | // scan list for Gnuplot program files
1738 | for (std::list::const_iterator i = ls.cbegin();
1739 | i != ls.cend(); ++i)
1740 | {
1741 | tmp = (*i) + "/" + Gnuplot::m_sGNUPlotFileName;
1742 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
1743 | if ( Gnuplot::file_exists(tmp, 0) ) // check existence
1744 | #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
1745 | if ( Gnuplot::file_exists(tmp, 1) ) // check existence and execution permission
1746 | #endif
1747 | {
1748 | Gnuplot::m_sGNUPlotPath = *i; // set m_sGNUPlotPath
1749 | return true;
1750 | }
1751 | }
1752 |
1753 | tmp = "Can't find gnuplot neither in PATH nor in \"" +
1754 | Gnuplot::m_sGNUPlotPath + "\"";
1755 | throw GnuplotException(tmp);
1756 | }
1757 |
1758 | //------------------------------------------------------------------------------
1759 | //
1760 | // check if file exists
1761 | //
1762 | bool Gnuplot::file_exists(const std::string &filename, int mode)
1763 | {
1764 | if ( mode < 0 || mode > 7)
1765 | {
1766 | throw std::runtime_error("In function \"Gnuplot::file_exists\": mode\
1767 | has to be an integer between 0 and 7");
1768 | }
1769 |
1770 | // int _access(const char *path, int mode);
1771 | // returns 0 if the file has the given mode,
1772 | // it returns -1 if the named file does not exist or is not accessible in
1773 | // the given mode
1774 | // mode = 0 (F_OK) (default): checks file for existence only
1775 | // mode = 1 (X_OK): execution permission
1776 | // mode = 2 (W_OK): write permission
1777 | // mode = 4 (R_OK): read permission
1778 | // mode = 6 : read and write permission
1779 | // mode = 7 : read, write and execution permission
1780 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
1781 | return (_access(filename.c_str(), mode) == 0);
1782 | #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
1783 | return (access(filename.c_str(), mode) == 0);
1784 | #endif
1785 | }
1786 |
1787 | bool Gnuplot::file_available(const std::string &filename)
1788 | {
1789 | std::ostringstream except;
1790 | if( Gnuplot::file_exists(filename, 0) ) // check existence
1791 | {
1792 | if( !(Gnuplot::file_exists(filename, 4)) ) // check read permission
1793 | {
1794 | except << "No read permission for File \"" << filename << "\"";
1795 | throw GnuplotException( except.str() );
1796 | }
1797 | return true;
1798 | }
1799 | except << "File \"" << filename << "\" does not exist";
1800 | throw GnuplotException( except.str() );
1801 | }
1802 |
1803 |
1804 |
1805 | //------------------------------------------------------------------------------
1806 | //
1807 | // Opens a temporary file
1808 | //
1809 | std::string Gnuplot::create_tmpfile(std::ofstream &tmp)
1810 | {
1811 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
1812 | char name[15] = {'g', 'n', 'u', 'p', 'l', 'o', 't', 'i', 'X', 'X', 'X', 'X', 'X', 'X', '\0'}; //tmp file in working directory
1813 | #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
1814 | char name[20] = {'/', 't', 'm', 'p', '/', 'g', 'n', 'u', 'p', 'l', 'o', 't', 'i', 'X', 'X', 'X', 'X', 'X', 'X', '\0'}; // tmp file in /tmp
1815 | #endif
1816 |
1817 | //
1818 | // check if maximum number of temporary files reached
1819 | //
1820 | if (Gnuplot::tmpfile_num == GP_MAX_TMP_FILES - 1)
1821 | {
1822 | std::ostringstream except;
1823 | except << "Maximum number of temporary files reached ("
1824 | << GP_MAX_TMP_FILES << "): cannot open more files" << std::endl;
1825 |
1826 | throw GnuplotException( except.str() );
1827 | }
1828 |
1829 | // int mkstemp(char *name);
1830 | // shall replace the contents of the string pointed to by "name" by a unique
1831 | // filename, and return a file descriptor for the file open for reading and
1832 | // writing. Otherwise, -1 shall be returned if no suitable file could be
1833 | // created. The string in template should look like a filename with six
1834 | // trailing 'X' s; mkstemp() replaces each 'X' with a character from the
1835 | // portable filename character set. The characters are chosen such that the
1836 | // resulting name does not duplicate the name of an existing file at the
1837 | // time of a call to mkstemp()
1838 |
1839 |
1840 | //
1841 | // open temporary files for output
1842 | //
1843 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
1844 | if (_mktemp(name) == nullptr)
1845 | #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
1846 | int tmpfd;
1847 | if ((tmpfd = mkstemp(name)) == -1)
1848 | #endif
1849 | {
1850 | std::ostringstream except;
1851 | except << "Cannot create temporary file \"" << name << "\"";
1852 | throw GnuplotException(except.str());
1853 | }
1854 | #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
1855 | (void)close(tmpfd);
1856 | #endif
1857 |
1858 | tmp.open(name);
1859 | if (tmp.bad())
1860 | {
1861 | std::ostringstream except;
1862 | except << "Cannot create temporary file \"" << name << "\"";
1863 | throw GnuplotException(except.str());
1864 | }
1865 |
1866 | //
1867 | // Save the temporary filename
1868 | //
1869 | tmpfile_list.push_back(name);
1870 | Gnuplot::tmpfile_num++;
1871 |
1872 | return name;
1873 | }
1874 |
1875 | void Gnuplot::remove_tmpfiles(void)
1876 | {
1877 | if ((tmpfile_list).size() > 0)
1878 | {
1879 | for (unsigned int i = 0U; i < tmpfile_list.size(); ++i)
1880 | {
1881 |
1882 | if( remove( tmpfile_list[i].c_str() ) != 0 )
1883 | {
1884 | std::ostringstream except;
1885 | except << "Cannot remove temporary file \"" << tmpfile_list[i] << "\"";
1886 | throw GnuplotException(except.str());
1887 | }
1888 | }
1889 |
1890 | Gnuplot::tmpfile_num -= static_cast(tmpfile_list.size());
1891 | }
1892 | }
1893 | #endif // GNUPLOT_I_HPP
1894 |
--------------------------------------------------------------------------------