Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
Loading...
Searching...
No Matches
logging::graphing Namespace Reference

Namespace containing all global type/structs that will be used project wide for graphing and plotting data with matplotlib. These graphing functions are built to be as feature rich as possible while still being easy to use. More...

Classes

class  PathTracer
 The PathTracer class is used to trace the path of the rover and plot the path on a 2D graph. More...
 

Functions

void PlotCoordinates2D (const std::vector< geoops::UTMCoordinate > &vCoordinates, const std::string &szTitle="UTMCoordinatePlot")
 Plot a 2D graph of UTM coordinates.
 
void PlotCoordinates2D (const std::vector< geoops::GPSCoordinate > &vCoordinates, const std::string &szTitle="GPSCoordinatePlot")
 Plot a 2D graph of GPS coordinates.
 
void PlotCoordinates2D (const std::vector< geoops::Waypoint > &vWaypoints, const std::string &szTitle="WaypointPlot")
 Plot a 2D graph of waypoints.
 
void PlotCoordinates3D (const std::vector< geoops::UTMCoordinate > &vCoordinates, const std::string &szTitle="UTMCoordinatePlot")
 Plot a 3D graph of UTM coordinates.
 
void PlotCoordinates3D (const std::vector< geoops::GPSCoordinate > &vCoordinates, const std::string &szTitle="GPSCoordinatePlot")
 Plot a 3D graph of GPS coordinates.
 
void PlotCoordinates3D (const std::vector< geoops::Waypoint > &vWaypoints, const std::string &szTitle="WaypointPlot")
 Plot a 3D graph of waypoints.
 

Detailed Description

Namespace containing all global type/structs that will be used project wide for graphing and plotting data with matplotlib. These graphing functions are built to be as feature rich as possible while still being easy to use.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-01-08
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-01-07

Function Documentation

◆ PlotCoordinates2D() [1/3]

void logging::graphing::PlotCoordinates2D ( const std::vector< geoops::UTMCoordinate > &  vCoordinates,
const std::string &  szTitle = "UTMCoordinatePlot" 
)
inline

Plot a 2D graph of UTM coordinates.

Parameters
vCoordinates- The vector of UTM coordinates to plot.
szTitle- The title of the plot. This will be the name of the file as well.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-01-07
53 {
54 // Create instance variables.
55 std::string szPlotTitle = szTitle;
56 matplot::figure_handle mtPlot = matplot::figure(true);
57 matplot::axes_handle mtAxes = mtPlot->current_axes();
58
59 // Check if the coordinates vector is empty.
60 if (vCoordinates.empty())
61 {
62 // Submit logger message.
63 LOG_WARNING(logging::g_qSharedLogger, "Coordinates vector is empty. Cannot plot.");
64 return;
65 }
66 // Check if the plot title is empty.
67 if (szPlotTitle.empty())
68 {
69 // Submit logger message.
70 LOG_WARNING(logging::g_qSharedLogger, "Plot title is empty. Setting title to default.");
71 szPlotTitle = "UTMCoordinatePlot";
72 }
73
74 // Check if a file with the same title name already exists. If so then append a number to the end of the file name and recheck.
75 std::string szFileName = logging::g_szLoggingOutputPath + "/path_plots/" + szTitle;
76 int nFileNum = 0;
77 while (std::filesystem::exists(szFileName + ".png"))
78 {
79 szFileName = szFileName + std::to_string(nFileNum);
80 ++nFileNum;
81 }
82
83 // Check if the final directory exists. If not then create it.
84 if (!std::filesystem::exists(logging::g_szLoggingOutputPath + "/path_plots"))
85 {
86 std::filesystem::create_directory(logging::g_szLoggingOutputPath + "/path_plots");
87 }
88 // Configure the matplotplusplus gnuplot backend to not display the plot, instead save it to a file.
89 mtPlot->backend()->output(szFileName + ".png");
90
91 // Use matplotplusplus to plot the UTM coordinates as red dots with blue lines connecting them.
92 std::vector<double> vEasting, vNorthing;
93 for (const geoops::UTMCoordinate& stCoordinate : vCoordinates)
94 {
95 vEasting.push_back(stCoordinate.dEasting);
96 vNorthing.push_back(stCoordinate.dNorthing);
97 }
98 mtAxes->plot(vEasting, vNorthing, "-o"); // blue lines with red dots
99 mtPlot->title(szPlotTitle);
100 mtAxes->xlabel("Easting");
101 mtAxes->ylabel("Northing");
102 // Set axis options.
103 mtAxes->grid(true);
104 mtAxes->xtickangle(45);
105 mtAxes->axis(matplot::square);
106 mtAxes->xtickformat("%.0f"); // No decimal places for x-axis
107 mtAxes->ytickformat("%.0f"); // No decimal places for y-axis
108 // Set the hold to false.
109 mtAxes->hold(false);
110
111 // Calculate and annotate distances between points
112 for (size_t i = 1; i < vCoordinates.size(); ++i)
113 {
114 double dDistance = std::sqrt(std::pow(vCoordinates[i].dEasting - vCoordinates[i - 1].dEasting, 2) +
115 std::pow(vCoordinates[i].dNorthing - vCoordinates[i - 1].dNorthing, 2));
116 double dMidEasting = (vCoordinates[i].dEasting + vCoordinates[i - 1].dEasting) / 2;
117 double dMidNorthing = (vCoordinates[i].dNorthing + vCoordinates[i - 1].dNorthing) / 2;
118 mtAxes->text(dMidEasting, dMidNorthing, std::to_string(int(dDistance)) + " m");
119 }
120
121 // Close the plot.
122 mtPlot->save(szFileName + ".png");
123 }
This struct stores/contains information about a UTM coordinate.
Definition GeospatialOperations.hpp:195
Here is the caller graph for this function:

◆ PlotCoordinates2D() [2/3]

void logging::graphing::PlotCoordinates2D ( const std::vector< geoops::GPSCoordinate > &  vCoordinates,
const std::string &  szTitle = "GPSCoordinatePlot" 
)
inline

Plot a 2D graph of GPS coordinates.

Parameters
vCoordinates- The vector of GPS coordinates to plot.
szTitle- The title of the plot. This will be the name of the file as well.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-01-07
135 {
136 // Create instance variables.
137 std::string szPlotTitle = szTitle;
138 matplot::figure_handle mtPlot = matplot::figure(true);
139 matplot::axes_handle mtAxes = mtPlot->current_axes();
140
141 // Check if the coordinates vector is empty.
142 if (vCoordinates.empty())
143 {
144 // Submit logger message.
145 LOG_WARNING(logging::g_qSharedLogger, "Coordinates vector is empty. Cannot plot.");
146 return;
147 }
148
149 // Check if the plot title is empty.
150 if (szPlotTitle.empty())
151 {
152 // Submit logger message.
153 LOG_WARNING(logging::g_qSharedLogger, "Plot title is empty. Setting title to default.");
154 szPlotTitle = "GPSCoordinatePlot";
155 }
156
157 // Check if a file with the same title name already exists. If so then append a number to the end of the file name and recheck.
158 std::string szFileName = logging::g_szLoggingOutputPath + "/path_plots/" + szTitle;
159 int nFileNum = 0;
160 while (std::filesystem::exists(szFileName + ".png"))
161 {
162 szFileName = szFileName + std::to_string(nFileNum);
163 ++nFileNum;
164 }
165
166 // Check if the final directory exists. If not then create it.
167 if (!std::filesystem::exists(logging::g_szLoggingOutputPath + "/path_plots"))
168 {
169 std::filesystem::create_directory(logging::g_szLoggingOutputPath + "/path_plots");
170 }
171 // Configure the matplotplusplus gnuplot backend to not display the plot, instead save it to a file.
172 mtPlot->backend()->output(szFileName + ".png");
173
174 // Use matplotplusplus to plot the UTM coordinates as red dots with blue lines connecting them.
175 std::vector<double> vLatitude, vLongitude;
176 for (const geoops::GPSCoordinate& stCoordinate : vCoordinates)
177 {
178 vLatitude.push_back(stCoordinate.dLatitude);
179 vLongitude.push_back(stCoordinate.dLongitude);
180 }
181 mtAxes->plot(vLatitude, vLongitude, "-o"); // blue lines with red dots
182 mtPlot->title(szPlotTitle);
183 mtAxes->xlabel("Latitude");
184 mtAxes->ylabel("Longitude");
185 // Set axis options.
186 mtAxes->grid(true);
187 mtAxes->xtickangle(45);
188 mtAxes->axis(matplot::square);
189 mtAxes->xtickformat("%.0f"); // No decimal places for x-axis
190 mtAxes->ytickformat("%.0f"); // No decimal places for y-axis
191 // Set the hold to false.
192 mtAxes->hold(false);
193
194 // Calculate and annotate distances between points
195 for (size_t i = 1; i < vCoordinates.size(); ++i)
196 {
197 double dDistance = geoops::CalculateGeoMeasurement(vCoordinates[i - 1], vCoordinates[i]).dDistanceMeters;
198 double dMidLatitude = (vCoordinates[i].dLatitude + vCoordinates[i - 1].dLatitude) / 2;
199 double dMidLongitude = (vCoordinates[i].dLongitude + vCoordinates[i - 1].dLongitude) / 2;
200 mtAxes->text(dMidLatitude, dMidLongitude, std::to_string(int(dDistance)) + " m");
201 }
202
203 // Close the plot.
204 mtPlot->save(szFileName + ".png");
205 }
GeoMeasurement CalculateGeoMeasurement(const GPSCoordinate &stCoord1, const GPSCoordinate &stCoord2)
The shortest path between two points on an ellipsoid at (lat1, lon1) and (lat2, lon2) is called the g...
Definition GeospatialOperations.hpp:522
This struct stores/contains information about a GPS data.
Definition GeospatialOperations.hpp:99
Here is the call graph for this function:

◆ PlotCoordinates2D() [3/3]

void logging::graphing::PlotCoordinates2D ( const std::vector< geoops::Waypoint > &  vWaypoints,
const std::string &  szTitle = "WaypointPlot" 
)
inline

Plot a 2D graph of waypoints.

Parameters
vWaypoints- The vector of waypoints to plot.
szTitle- The title of the plot. This will be the name of the file as well.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-01-07
217 {
218 // Create instance variables.
219 std::string szPlotTitle = szTitle;
220 matplot::figure_handle mtPlot = matplot::figure(true);
221 matplot::axes_handle mtAxes = mtPlot->current_axes();
222
223 // Check if the coordinates vector is empty.
224 if (vWaypoints.empty())
225 {
226 // Submit logger message.
227 LOG_WARNING(logging::g_qSharedLogger, "Waypoints vector is empty. Cannot plot.");
228 return;
229 }
230
231 // Check if the plot title is empty.
232 if (szPlotTitle.empty())
233 {
234 // Submit logger message.
235 LOG_WARNING(logging::g_qSharedLogger, "Plot title is empty. Setting title to default.");
236 szPlotTitle = "WaypointPlot";
237 }
238
239 // Check if a file with the same title name already exists. If so then append a number to the end of the file name and recheck.
240 std::string szFileName = logging::g_szLoggingOutputPath + "/path_plots/" + szTitle;
241 int nFileNum = 0;
242 while (std::filesystem::exists(szFileName + ".png"))
243 {
244 szFileName = szFileName + std::to_string(nFileNum);
245 ++nFileNum;
246 }
247
248 // Check if the final directory exists. If not then create it.
249 if (!std::filesystem::exists(logging::g_szLoggingOutputPath + "/path_plots"))
250 {
251 std::filesystem::create_directory(logging::g_szLoggingOutputPath + "/path_plots");
252 }
253 // Configure the matplotplusplus gnuplot backend to not display the plot, instead save it to a file.
254 mtPlot->backend()->output(szFileName + ".png");
255
256 // Use matplotplusplus to plot the UTM coordinates as red dots with blue lines connecting them.
257 std::vector<double> vEasting, vNorthing;
258 for (const geoops::Waypoint& stWaypoint : vWaypoints)
259 {
260 vEasting.push_back(stWaypoint.GetUTMCoordinate().dEasting);
261 vNorthing.push_back(stWaypoint.GetUTMCoordinate().dNorthing);
262 }
263 mtAxes->plot(vEasting, vNorthing, "-o");
264 mtPlot->title(szPlotTitle);
265 mtAxes->xlabel("Easting");
266 mtAxes->ylabel("Northing");
267 // Set axis options.
268 mtAxes->grid(true);
269 mtAxes->xtickangle(45);
270 mtAxes->axis(matplot::square);
271 mtAxes->xtickformat("%.0f"); // No decimal places for x-axis
272 mtAxes->ytickformat("%.0f"); // No decimal places for y-axis
273 // Set the hold to false.
274 mtAxes->hold(false);
275
276 // Calculate and annotate distances between points.
277 for (size_t i = 1; i < vWaypoints.size(); ++i)
278 {
279 double dDistance = geoops::CalculateGeoMeasurement(vWaypoints[i - 1].GetUTMCoordinate(), vWaypoints[i].GetUTMCoordinate()).dDistanceMeters;
280 double dMidEasting = (vWaypoints[i].GetUTMCoordinate().dEasting + vWaypoints[i - 1].GetUTMCoordinate().dEasting) / 2;
281 double dMidNorthing = (vWaypoints[i].GetUTMCoordinate().dNorthing + vWaypoints[i - 1].GetUTMCoordinate().dNorthing) / 2;
282 mtAxes->text(dMidEasting, dMidNorthing, std::to_string(int(dDistance)) + " m");
283 }
284
285 // Close the plot.
286 mtPlot->save(szFileName + ".png");
287 }
This struct is used by the WaypointHandler class to store location, size, and type information about ...
Definition GeospatialOperations.hpp:392
Here is the call graph for this function:

◆ PlotCoordinates3D() [1/3]

void logging::graphing::PlotCoordinates3D ( const std::vector< geoops::UTMCoordinate > &  vCoordinates,
const std::string &  szTitle = "UTMCoordinatePlot" 
)
inline

Plot a 3D graph of UTM coordinates.

Parameters
vCoordinates- The vector of UTM coordinates to plot.
szTitle- The title of the plot. This will be the name of the file as well.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-01-08
299 {
300 // Create instance variables.
301 std::string szPlotTitle = szTitle;
302 matplot::figure_handle mtPlot = matplot::figure(true);
303 matplot::axes_handle mtAxes = mtPlot->current_axes();
304
305 // Check if the coordinates vector is empty.
306 if (vCoordinates.empty())
307 {
308 // Submit logger message.
309 LOG_WARNING(logging::g_qSharedLogger, "Coordinates vector is empty. Cannot plot.");
310 return;
311 }
312
313 // Check if the plot title is empty.
314 if (szPlotTitle.empty())
315 {
316 // Submit logger message.
317 LOG_WARNING(logging::g_qSharedLogger, "Plot title is empty. Setting title to default.");
318 szPlotTitle = "UTMCoordinatePlot";
319 }
320
321 // Check if a file with the same title name already exists. If so then append a number to the end of the file name and recheck.
322 std::string szFileName = logging::g_szLoggingOutputPath + "/path_plots/" + szTitle;
323 int nFileNum = 0;
324 while (std::filesystem::exists(szFileName + ".png"))
325 {
326 szFileName = szFileName + std::to_string(nFileNum);
327 ++nFileNum;
328 }
329
330 // Check if the final directory exists. If not then create it.
331 if (!std::filesystem::exists(logging::g_szLoggingOutputPath + "/path_plots"))
332 {
333 std::filesystem::create_directory(logging::g_szLoggingOutputPath + "/path_plots");
334 }
335 // Configure the matplotplusplus gnuplot backend to not display the plot, instead save it to a file.
336 mtPlot->backend()->output(szFileName + ".png");
337
338 // Use matplotplusplus to plot the UTM coordinates as red dots with blue lines connecting them.
339 std::vector<double> vEasting, vNorthing, vAltitude;
340 for (const geoops::UTMCoordinate& stCoordinate : vCoordinates)
341 {
342 vEasting.push_back(stCoordinate.dEasting);
343 vNorthing.push_back(stCoordinate.dNorthing);
344 vAltitude.push_back(stCoordinate.dAltitude);
345 }
346 // Create a 3D plot
347 mtAxes->plot3(vEasting, vNorthing, vAltitude, "-o");
348 mtPlot->title(szPlotTitle);
349 mtAxes->xlabel("Easting");
350 mtAxes->ylabel("Northing");
351 mtAxes->zlabel("Altitude");
352 // Set axis options.
353 mtAxes->grid(true);
354 mtAxes->xtickangle(45);
355 mtAxes->axis(matplot::square);
356 mtAxes->xtickformat("%.0f"); // No decimal places for x-axis
357 mtAxes->ytickformat("%.0f"); // No decimal places for y-axis
358 mtAxes->ztickformat("%.0f"); // No decimal places for z-axis
359 // Set the hold to false.
360 mtAxes->hold(false);
361
362 // Close the plot.
363 mtPlot->save(szFileName + ".png");
364 }

◆ PlotCoordinates3D() [2/3]

void logging::graphing::PlotCoordinates3D ( const std::vector< geoops::GPSCoordinate > &  vCoordinates,
const std::string &  szTitle = "GPSCoordinatePlot" 
)
inline

Plot a 3D graph of GPS coordinates.

Parameters
vCoordinates- The vector of GPS coordinates to plot.
szTitle- The title of the plot. This will be the name of the file as well.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-01-08
376 {
377 // Create instance variables.
378 std::string szPlotTitle = szTitle;
379 matplot::figure_handle mtPlot = matplot::figure(true);
380 matplot::axes_handle mtAxes = mtPlot->current_axes();
381
382 // Check if the coordinates vector is empty.
383 if (vCoordinates.empty())
384 {
385 // Submit logger message.
386 LOG_WARNING(logging::g_qSharedLogger, "Coordinates vector is empty. Cannot plot.");
387 return;
388 }
389
390 // Check if the plot title is empty.
391 if (szPlotTitle.empty())
392 {
393 // Submit logger message.
394 LOG_WARNING(logging::g_qSharedLogger, "Plot title is empty. Setting title to default.");
395 szPlotTitle = "GPSCoordinatePlot";
396 }
397
398 // Check if a file with the same title name already exists. If so then append a number to the end of the file name and recheck.
399 std::string szFileName = logging::g_szLoggingOutputPath + "/path_plots/" + szTitle;
400 int nFileNum = 0;
401 while (std::filesystem::exists(szFileName + ".png"))
402 {
403 szFileName = szFileName + std::to_string(nFileNum);
404 ++nFileNum;
405 }
406
407 // Check if the final directory exists. If not then create it.
408 if (!std::filesystem::exists(logging::g_szLoggingOutputPath + "/path_plots"))
409 {
410 std::filesystem::create_directory(logging::g_szLoggingOutputPath + "/path_plots");
411 }
412 // Configure the matplotplusplus gnuplot backend to not display the plot, instead save it to a file.
413 mtPlot->backend()->output(szFileName + ".png");
414
415 // Use matplotplusplus to plot the UTM coordinates as red dots with blue lines connecting them.
416 std::vector<double> vLatitude, vLongitude, vAltitude;
417 for (const geoops::GPSCoordinate& stCoordinate : vCoordinates)
418 {
419 vLatitude.push_back(stCoordinate.dLatitude);
420 vLongitude.push_back(stCoordinate.dLongitude);
421 vAltitude.push_back(stCoordinate.dAltitude);
422 }
423 // Create a 3D plot
424 mtAxes->plot3(vLatitude, vLongitude, vAltitude, "-o");
425 mtPlot->title(szPlotTitle);
426 mtAxes->xlabel("Latitude");
427 mtAxes->ylabel("Longitude");
428 mtAxes->zlabel("Altitude");
429 // Set axis options.
430 mtAxes->grid(true);
431 mtAxes->xtickangle(45);
432 mtAxes->axis(matplot::square);
433 mtAxes->xtickformat("%.0f"); // No decimal places for x-axis
434 mtAxes->ytickformat("%.0f"); // No decimal places for y-axis
435 mtAxes->ztickformat("%.0f"); // No decimal places for z-axis
436 // Set the hold to false.
437 mtAxes->hold(false);
438
439 // Close the plot.
440 mtPlot->save(szFileName + ".png");
441 }

◆ PlotCoordinates3D() [3/3]

void logging::graphing::PlotCoordinates3D ( const std::vector< geoops::Waypoint > &  vWaypoints,
const std::string &  szTitle = "WaypointPlot" 
)
inline

Plot a 3D graph of waypoints.

Parameters
vWaypoints- The vector of waypoints to plot.
szTitle- The title of the plot. This will be the name of the file as well.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-01-08
453 {
454 // Create instance variables.
455 std::string szPlotTitle = szTitle;
456 matplot::figure_handle mtPlot = matplot::figure(true);
457 matplot::axes_handle mtAxes = mtPlot->current_axes();
458
459 // Check if the coordinates vector is empty.
460 if (vWaypoints.empty())
461 {
462 // Submit logger message.
463 LOG_WARNING(logging::g_qSharedLogger, "Waypoints vector is empty. Cannot plot.");
464 return;
465 }
466
467 // Check if the plot title is empty.
468 if (szPlotTitle.empty())
469 {
470 // Submit logger message.
471 LOG_WARNING(logging::g_qSharedLogger, "Plot title is empty. Setting title to default.");
472 szPlotTitle = "WaypointPlot";
473 }
474
475 // Check if a file with the same title name already exists. If so then append a number to the end of the file name and recheck.
476 std::string szFileName = logging::g_szLoggingOutputPath + "/path_plots/" + szTitle;
477 int nFileNum = 0;
478 while (std::filesystem::exists(szFileName + ".png"))
479 {
480 szFileName = szFileName + std::to_string(nFileNum);
481 ++nFileNum;
482 }
483
484 // Check if the final directory exists. If not then create it.
485 if (!std::filesystem::exists(logging::g_szLoggingOutputPath + "/path_plots"))
486 {
487 std::filesystem::create_directory(logging::g_szLoggingOutputPath + "/path_plots");
488 }
489 // Configure the matplotplusplus gnuplot backend to not display the plot, instead save it to a file.
490 mtPlot->backend()->output(szFileName + ".png");
491
492 // Use matplotplusplus to plot the UTM coordinates as red dots with blue lines connecting them.
493 std::vector<double> vEasting, vNorthing, vAltitude;
494 for (const geoops::Waypoint& stWaypoint : vWaypoints)
495 {
496 vEasting.push_back(stWaypoint.GetUTMCoordinate().dEasting);
497 vNorthing.push_back(stWaypoint.GetUTMCoordinate().dNorthing);
498 vAltitude.push_back(stWaypoint.GetUTMCoordinate().dAltitude);
499 }
500 // Create a 3D plot
501 mtAxes->plot3(vEasting, vNorthing, vAltitude, "-o");
502 mtPlot->title(szPlotTitle);
503 mtAxes->xlabel("Easting");
504 mtAxes->ylabel("Northing");
505 mtAxes->zlabel("Altitude");
506 // Set axis options.
507 mtAxes->grid(true);
508 mtAxes->xtickangle(45);
509 mtAxes->axis(matplot::square);
510 mtAxes->xtickformat("%.0f"); // No decimal places for x-axis
511 mtAxes->ytickformat("%.0f"); // No decimal places for y-axis
512 mtAxes->ztickformat("%.0f"); // No decimal places for z-axis
513 // Set the hold to false.
514 mtAxes->hold(false);
515
516 // Close the plot.
517 mtPlot->save(szFileName + ".png");
518 }