📄 gnuplot.c
字号:
#include "gnuplot.h"#include <unistd.h>// dirty hack#if !defined X_OK#define X_OK 1#endifusing namespace leda;#if defined(LEDA_STD_IO_HEADERS)using std::cout;using std::endl;#endifconst char* const gp_style::name = "gp_style";const char* const gp_style::str[gp_style::size] = { "lines", "points", "linespoints", "impulses", "dots", "steps", "errorbars", "boxes", "boxerrorbars" };const gp_style::num gp_style::lines = 0;const gp_style::num gp_style::points = 1;const gp_style::num gp_style::linespoints = 2;const gp_style::num gp_style::impulses = 3;const gp_style::num gp_style::dots = 4;const gp_style::num gp_style::steps = 5;const gp_style::num gp_style::errorbars = 6;const gp_style::num gp_style::boxes = 7;const gp_style::num gp_style::boxerrorbars = 8;const char* gp_style::get(gp_style::num arg) { return gp_style::str[arg]; }bool gp_style::check_arg(int arg) { return (arg < gp_style::min || arg > gp_style::max) ? false : true;}/* --- gp_terminal ------------------------------------------------------- */const char* const gp_terminal::name = "gp_terminal";const char* const gp_terminal::str[gp_terminal::size] = { "x11", "postscript color", "pslatex", "png"};const gp_terminal::num gp_terminal::x11 = 0;const gp_terminal::num gp_terminal::postscript = 1;const gp_terminal::num gp_terminal::pslatex = 2;const gp_terminal::num gp_terminal::png = 3;const char* gp_terminal::get(gp_terminal::num arg) { return gp_terminal::str[arg]; }bool gp_terminal::check_arg(int arg) { return (arg < gp_terminal::min || arg > gp_terminal::max) ? false : true;}/* ----------------------------------------------------------------------- */const char* const gnuplot_ctrl::default_font = "Courier";const int gnuplot_ctrl::default_font_size = 12;void gnuplot_ctrl::init(){ if (get_program_path("gnuplot") == NULL) { error("init", "cannot find gnuplot in your PATH!"); return; } nplots = 0; ntmp = 0; set_style(gp_style::points); gnucmd = popen("gnuplot", "w"); if (gnucmd == NULL) error("init", "error starting gnuplot!");}bool gnuplot_ctrl::check_x_display(){ if (getenv("DISPLAY") == NULL) { error("check_x_display", "can't find DISPLAY variable!"); return false; } return true;}char* gnuplot_ctrl::get_program_path(const char* pname){ sprintf(buffer, "./%s", pname); if (access(buffer, X_OK) == 0) { sprintf(buffer, "."); return buffer; } buffer[0] = 0; int i, j, len; char* path = getenv("PATH"); if (path != NULL) { for (i = 0; path[i]; ) { for (j = i; (path[j]) && (path[j]!=':'); j++); len = j - i; strncpy(buffer, path + i, len); if (len == 0) buffer[len++] = '.'; buffer[len++] = '/'; strcpy(buffer + len, pname); if (access(buffer, X_OK) == 0) break; buffer[0] = 0; i = j; if (path[i] == ':') i++; } } else error("get_program_path", "PATH variable not set!"); if (buffer[0] == 0) return NULL; len = strlen(buffer) - 1; while (buffer[len] != '/') buffer[len--] = 0; buffer[len] = 0; return buffer;}char* gnuplot_ctrl::get_tmpname(int n) { sprintf(buffer, "gp%d", n); return buffer;}bool gnuplot_ctrl::create_tmpfile(ofstream& fout, const char* fname){ if (ntmp == gnuplot_ctrl::TMP_FILES - 1) { error("create_tmpfile", "Maximum number of temporary files reached,\ can't open more!"); return false; } fout.open(fname); if (!fout.is_open()) { error("create_tmpfile", "Can't open temporary file for writing!"); return false; } ntmp++; return true;}void gnuplot_ctrl::plot_user_data(const char* fname, const char* title){ if (nplots > 0) { if (title == NULL) sprintf(cmd, "replot \"%s\" with %s", fname, pstyle); else sprintf(cmd, "replot \"%s\" title \"%s\" with %s", fname, title, pstyle); } else { if (title == NULL) sprintf(cmd, "plot \"%s\" with %s", fname, pstyle); else sprintf(cmd, "plot \"%s\" title \"%s\" with %s", fname, title, pstyle); } command(cmd); nplots++;}/* ---- public members --------------------------------------------------- */void gnuplot_ctrl::command(const char* cmd_str, ...){ va_list ap; va_start(ap, cmd_str); vsprintf(buffer, cmd_str, ap); va_end(ap); strcat(buffer, "\n"); fputs(buffer, gnucmd); fflush(gnucmd);}void gnuplot_ctrl::set_title(const char* title, int x, int y, const char* font, int size){ sprintf(cmd, "set title \"%s\" %d, %d \"%s,%d\"", title, x, y, font, size); command(cmd);}void gnuplot_ctrl::set_samples(int i){ sprintf(cmd, "set samples %d", i); command(cmd);}void gnuplot_ctrl::set_isosamples(int i){ sprintf(cmd, "set isosamples %d", i); command(cmd);}void gnuplot_ctrl::set_output(const char* fname){ sprintf(cmd, "set output \"%s\"", fname); command(cmd);}void gnuplot_ctrl::set_terminal(gp_terminal::num term){ if (term == gp_terminal::x11 && !check_x_display()) return; sprintf(cmd, "set term %s", gp_terminal::get(term)); command(cmd);}/* axis */void gnuplot_ctrl::set_xlabel(const char* label, int x, int y, const char* font, int size){ sprintf(cmd, "set xlabel \"%s\" %d, %d \"%s,%d\"", label, x, y, font, size); command(cmd);}void gnuplot_ctrl::set_xrange(const char* min, const char* max){ sprintf(cmd, "set xrange [%s:%s]", min, max); command(cmd);}void gnuplot_ctrl::set_ylabel(const char* label, int x, int y, const char* font, int size){ sprintf(cmd, "set ylabel \"%s\" %d, %d \"%s,%d\"", label, x, y, font, size); command(cmd);}void gnuplot_ctrl::set_yrange(const char* min, const char* max){ sprintf(cmd, "set yrange [%s:%s]", min, max); command(cmd);}void gnuplot_ctrl::set_zlabel(const char* label, int x, int y, const char* font, int size){ sprintf(cmd, "set zlabel \"%s\" %d, %d \"%s,%d\"", label, x, y, font, size); command(cmd);}void gnuplot_ctrl::set_zrange(const char* min, const char* max){ sprintf(cmd, "set zrange [%s:%s]", min, max); command(cmd);}void gnuplot_ctrl::set_timestamp(const char* format, int xoff, int yoff, const char* font){ sprintf(cmd, "set timestamp \"%s\" %d,%d \"%s\"\n", format, xoff, yoff, font); fputs(cmd, gnucmd); fflush(gnucmd);} void gnuplot_ctrl::set_style(gp_style::num style) { strcpy(pstyle, gp_style::get(style));}void gnuplot_ctrl::reset_plot(){//for (int i = 0; i < ntmp; i++) remove(get_tmpname(i)); ntmp = 0; nplots = 0;}void gnuplot_ctrl::replot(){ if (nplots == 0) return; command("replot");}void gnuplot_ctrl::close(){ if (gnucmd == 0) return; //for (int i = 0; i < ntmp; i++) remove(get_tmpname(i)); ntmp = 0; if (pclose(gnucmd) == -1) error("close", "problem closing communication to gnuplot!"); gnucmd = 0;}void gnuplot_ctrl::plot_x(double* d, int n, const char* title){ if (d == NULL || (n < 1)) return; char* name = get_tmpname(ntmp); ofstream fout; if (!create_tmpfile(fout, name)) return; for (int i = 0; i < n; i++) fout << d[i] << endl; fout.flush(); fout.close(); plot_user_data(name, title);}void gnuplot_ctrl::plot_xy(double* x, double* y, int n, const char* title){ if (x == NULL || y == NULL || (n < 1)) return; char* name = get_tmpname(ntmp); ofstream fout; if (!create_tmpfile(fout, name)) return; for (int i = 0; i < n; i++) fout << x[i] << " " << y[i] << endl; fout.flush(); fout.close(); plot_user_data(name, title);}void gnuplot_ctrl::plot_slope(double a, double b, const char* title){ if (nplots > 0) sprintf(cmd, "replot %g * x + %g title \"%s\" with %s", a, b, title, pstyle); else sprintf(cmd, "plot %g * x + %g title \"%s\" with %s", a, b, title, pstyle); command(cmd); nplots++;}void gnuplot_ctrl::plot_equation(char* equation, const char* title){ if (nplots > 0) sprintf(cmd, "replot %s title \"%s\" with %s", equation, title, pstyle); else sprintf(cmd, "plot %s title \"%s\" with %s", equation, title, pstyle); command(cmd); nplots++;}void gnuplot_ctrl::splot_equation(char* equation, const char* title){ if (nplots > 0) sprintf(cmd, "replot %s title \"%s\" with %s", equation, title, pstyle); else sprintf(cmd, "splot %s title \"%s\" with %s", equation, title, pstyle); command(cmd); nplots++;}/* --- non member functions ---------------------------------------------- */void gnuplot_plot(double* x, double* y, int n, gp_style::num style, const char* title, const char* label_x, const char* label_y){ if (x == NULL || n < 1) return; gnuplot_ctrl handle; handle.set_style(style); handle.set_xlabel(label_x); handle.set_ylabel(label_y); if (y == NULL) handle.plot_x(x, n, title); else handle.plot_xy(x, y, n, title); cout << "press ENTER to continue\n"; while (getchar()!='\n'); handle.close();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -