calc-graph.el 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509
  1. ;;; calc-graph.el --- graph output functions for Calc
  2. ;; Copyright (C) 1990-1993, 2001-2017 Free Software Foundation, Inc.
  3. ;; Author: David Gillespie <daveg@synaptics.com>
  4. ;; This file is part of GNU Emacs.
  5. ;; GNU Emacs is free software: you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation, either version 3 of the License, or
  8. ;; (at your option) any later version.
  9. ;; GNU Emacs is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Commentary:
  16. ;;; Code:
  17. ;; This file is autoloaded from calc-ext.el.
  18. (require 'calc-ext)
  19. (require 'calc-macs)
  20. ;;; Graphics
  21. ;; The following three variables are customizable and defined in calc.el.
  22. (defvar calc-gnuplot-name)
  23. (defvar calc-gnuplot-plot-command)
  24. (defvar calc-gnuplot-print-command)
  25. (defvar calc-gnuplot-tempfile "calc")
  26. (defvar calc-gnuplot-default-device)
  27. (defvar calc-gnuplot-default-output)
  28. (defvar calc-gnuplot-print-device)
  29. (defvar calc-gnuplot-print-output)
  30. (defvar calc-gnuplot-keep-outfile nil)
  31. (defvar calc-gnuplot-version nil)
  32. (defvar calc-gnuplot-display (getenv "DISPLAY"))
  33. (defvar calc-gnuplot-geometry)
  34. (defvar calc-graph-default-resolution)
  35. (defvar calc-graph-default-resolution-3d)
  36. (defvar calc-graph-default-precision 5)
  37. (defvar calc-gnuplot-buffer nil)
  38. (defvar calc-gnuplot-input nil)
  39. (defvar calc-gnuplot-last-error-pos 1)
  40. (defvar calc-graph-last-device nil)
  41. (defvar calc-graph-last-output nil)
  42. (defvar calc-graph-file-cache nil)
  43. (defvar calc-graph-var-cache nil)
  44. (defvar calc-graph-data-cache nil)
  45. (defvar calc-graph-data-cache-limit 10)
  46. (defvar calc-graph-no-auto-view nil)
  47. (defvar calc-graph-no-wait nil)
  48. (defvar calc-gnuplot-trail-mark)
  49. (defun calc-graph-fast (many)
  50. (interactive "P")
  51. (let ((calc-graph-no-auto-view t))
  52. (calc-graph-delete t)
  53. (calc-graph-add many)
  54. (calc-graph-plot nil)))
  55. (defun calc-graph-fast-3d (many)
  56. (interactive "P")
  57. (let ((calc-graph-no-auto-view t))
  58. (calc-graph-delete t)
  59. (calc-graph-add-3d many)
  60. (calc-graph-plot nil)))
  61. (defun calc-graph-delete (all)
  62. (interactive "P")
  63. (calc-wrapper
  64. (calc-graph-init)
  65. (with-current-buffer calc-gnuplot-input
  66. (and (calc-graph-find-plot t all)
  67. (progn
  68. (if (looking-at "s?plot")
  69. (progn
  70. (setq calc-graph-var-cache nil)
  71. (delete-region (point) (point-max)))
  72. (delete-region (point) (1- (point-max)))))))
  73. (calc-graph-view-commands)))
  74. (defun calc-graph-find-plot (&optional before all)
  75. (goto-char (point-min))
  76. (and (re-search-forward "^s?plot[ \t]+" nil t)
  77. (let ((beg (point)))
  78. (goto-char (point-max))
  79. (if (or all
  80. (not (search-backward "," nil t))
  81. (< (point) beg))
  82. (progn
  83. (goto-char beg)
  84. (if before
  85. (beginning-of-line)))
  86. (or before
  87. (re-search-forward ",[ \t]+")))
  88. t)))
  89. (defun calc-graph-add (many)
  90. (interactive "P")
  91. (calc-wrapper
  92. (calc-graph-init)
  93. (cond ((null many)
  94. (calc-graph-add-curve (calc-graph-lookup (calc-top-n 2))
  95. (calc-graph-lookup (calc-top-n 1))))
  96. ((or (consp many) (eq many 0))
  97. (let ((xdata (calc-graph-lookup (calc-top-n 2)))
  98. (ylist (calc-top-n 1)))
  99. (or (eq (car-safe ylist) 'vec)
  100. (error "Y argument must be a vector"))
  101. (while (setq ylist (cdr ylist))
  102. (calc-graph-add-curve xdata (calc-graph-lookup (car ylist))))))
  103. ((> (setq many (prefix-numeric-value many)) 0)
  104. (let ((xdata (calc-graph-lookup (calc-top-n (1+ many)))))
  105. (while (> many 0)
  106. (calc-graph-add-curve xdata
  107. (calc-graph-lookup (calc-top-n many)))
  108. (setq many (1- many)))))
  109. (t
  110. (let (pair)
  111. (setq many (- many))
  112. (while (> many 0)
  113. (setq pair (calc-top-n many))
  114. (or (and (eq (car-safe pair) 'vec)
  115. (= (length pair) 3))
  116. (error "Argument must be an [x,y] vector"))
  117. (calc-graph-add-curve (calc-graph-lookup (nth 1 pair))
  118. (calc-graph-lookup (nth 2 pair)))
  119. (setq many (1- many))))))
  120. (calc-graph-view-commands)))
  121. (defun calc-graph-add-3d (many)
  122. (interactive "P")
  123. (calc-wrapper
  124. (calc-graph-init)
  125. (cond ((null many)
  126. (calc-graph-add-curve (calc-graph-lookup (calc-top-n 3))
  127. (calc-graph-lookup (calc-top-n 2))
  128. (calc-graph-lookup (calc-top-n 1))))
  129. ((or (consp many) (eq many 0))
  130. (let ((xdata (calc-graph-lookup (calc-top-n 3)))
  131. (ydata (calc-graph-lookup (calc-top-n 2)))
  132. (zlist (calc-top-n 1)))
  133. (or (eq (car-safe zlist) 'vec)
  134. (error "Z argument must be a vector"))
  135. (while (setq zlist (cdr zlist))
  136. (calc-graph-add-curve xdata ydata
  137. (calc-graph-lookup (car zlist))))))
  138. ((> (setq many (prefix-numeric-value many)) 0)
  139. (let ((xdata (calc-graph-lookup (calc-top-n (+ many 2))))
  140. (ydata (calc-graph-lookup (calc-top-n (+ many 1)))))
  141. (while (> many 0)
  142. (calc-graph-add-curve xdata ydata
  143. (calc-graph-lookup (calc-top-n many)))
  144. (setq many (1- many)))))
  145. (t
  146. (let (curve)
  147. (setq many (- many))
  148. (while (> many 0)
  149. (setq curve (calc-top-n many))
  150. (or (and (eq (car-safe curve) 'vec)
  151. (= (length curve) 4))
  152. (error "Argument must be an [x,y,z] vector"))
  153. (calc-graph-add-curve (calc-graph-lookup (nth 1 curve))
  154. (calc-graph-lookup (nth 2 curve))
  155. (calc-graph-lookup (nth 3 curve)))
  156. (setq many (1- many))))))
  157. (calc-graph-view-commands)))
  158. (defun calc-graph-add-curve (xdata ydata &optional zdata)
  159. (let ((num (calc-graph-count-curves))
  160. (pstyle (calc-var-value 'var-PointStyles))
  161. (lstyle (calc-var-value 'var-LineStyles)))
  162. (with-current-buffer calc-gnuplot-input
  163. (goto-char (point-min))
  164. (if (re-search-forward (if zdata "^plot[ \t]" "^splot[ \t]")
  165. nil t)
  166. (error "Can't mix 2d and 3d curves on one graph"))
  167. (if (re-search-forward "^s?plot[ \t]" nil t)
  168. (progn
  169. (end-of-line)
  170. (insert ", "))
  171. (goto-char (point-max))
  172. (or (eq (preceding-char) ?\n)
  173. (insert "\n"))
  174. (insert (if zdata "splot" "plot") " \n")
  175. (forward-char -1))
  176. (insert "{" (symbol-name (nth 1 xdata))
  177. ":" (symbol-name (nth 1 ydata)))
  178. (if zdata
  179. (insert ":" (symbol-name (nth 1 zdata))))
  180. (insert "} "
  181. "title \"" (symbol-name (nth 1 ydata)) "\" "
  182. "with dots")
  183. (setq pstyle (and (eq (car-safe pstyle) 'vec) (nth (1+ num) pstyle)))
  184. (setq lstyle (and (eq (car-safe lstyle) 'vec) (nth (1+ num) lstyle))))
  185. (calc-graph-set-styles
  186. (or (and (Math-num-integerp lstyle) (math-trunc lstyle))
  187. 0)
  188. (or (and (Math-num-integerp pstyle) (math-trunc pstyle))
  189. (if (eq (car-safe (calc-var-value (nth 2 ydata))) 'vec)
  190. 0 -1))
  191. (math-contains-sdev-p (eval (nth 2 ydata))))))
  192. (defun calc-graph-lookup (thing)
  193. (if (and (eq (car-safe thing) 'var)
  194. (calc-var-value (nth 2 thing)))
  195. thing
  196. (let ((found (assoc thing calc-graph-var-cache)))
  197. (or found
  198. (let ((varname (concat "PlotData"
  199. (int-to-string
  200. (1+ (length calc-graph-var-cache)))))
  201. var)
  202. (setq var (list 'var (intern varname)
  203. (intern (concat "var-" varname)))
  204. found (cons thing var)
  205. calc-graph-var-cache (cons found calc-graph-var-cache))
  206. (set (nth 2 var) thing)))
  207. (cdr found))))
  208. (defun calc-graph-juggle (arg)
  209. (interactive "p")
  210. (calc-graph-init)
  211. (with-current-buffer calc-gnuplot-input
  212. (if (< arg 0)
  213. (let ((num (calc-graph-count-curves)))
  214. (if (> num 0)
  215. (while (< arg 0)
  216. (setq arg (+ arg num))))))
  217. (while (>= (setq arg (1- arg)) 0)
  218. (calc-graph-do-juggle))))
  219. (defun calc-graph-count-curves ()
  220. (with-current-buffer calc-gnuplot-input
  221. (if (re-search-forward "^s?plot[ \t]" nil t)
  222. (let ((num 1))
  223. (goto-char (point-min))
  224. (while (search-forward "," nil t)
  225. (setq num (1+ num)))
  226. num)
  227. 0)))
  228. (defun calc-graph-do-juggle ()
  229. (let (base)
  230. (and (calc-graph-find-plot t t)
  231. (progn
  232. (setq base (point))
  233. (calc-graph-find-plot t nil)
  234. (or (eq base (point))
  235. (let ((str (buffer-substring (+ (point) 2) (1- (point-max)))))
  236. (delete-region (point) (1- (point-max)))
  237. (goto-char (+ base 5))
  238. (insert str ", ")))))))
  239. (defun calc-graph-print (flag)
  240. (interactive "P")
  241. (calc-graph-plot flag t))
  242. (defvar var-DUMMY)
  243. (defvar var-DUMMY2)
  244. (defvar var-PlotRejects)
  245. ;; The following variables are local to calc-graph-plot, but are
  246. ;; used in the functions calc-graph-compute-2d, calc-graph-refine-2d,
  247. ;; calc-graph-recompute-2d, calc-graph-compute-3d and
  248. ;; calc-graph-format-data, which are called by calc-graph-plot.
  249. (defvar calc-graph-yvalue)
  250. (defvar calc-graph-yvec)
  251. (defvar calc-graph-numsteps)
  252. (defvar calc-graph-numsteps3)
  253. (defvar calc-graph-xvalue)
  254. (defvar calc-graph-xvec)
  255. (defvar calc-graph-xname)
  256. (defvar calc-graph-yname)
  257. (defvar calc-graph-xstep)
  258. (defvar calc-graph-ycache)
  259. (defvar calc-graph-ycacheptr)
  260. (defvar calc-graph-refine)
  261. (defvar calc-graph-keep-file)
  262. (defvar calc-graph-xval)
  263. (defvar calc-graph-xlow)
  264. (defvar calc-graph-xhigh)
  265. (defvar calc-graph-yval)
  266. (defvar calc-graph-yp)
  267. (defvar calc-graph-xp)
  268. (defvar calc-graph-zp)
  269. (defvar calc-graph-yvector)
  270. (defvar calc-graph-resolution)
  271. (defvar calc-graph-y3value)
  272. (defvar calc-graph-y3name)
  273. (defvar calc-graph-y3step)
  274. (defvar calc-graph-zval)
  275. (defvar calc-graph-stepcount)
  276. (defvar calc-graph-is-splot)
  277. (defvar calc-graph-surprise-splot)
  278. (defvar calc-graph-blank)
  279. (defvar calc-graph-non-blank)
  280. (defvar calc-graph-curve-num)
  281. (defun calc-graph-plot (flag &optional printing)
  282. (interactive "P")
  283. (calc-slow-wrapper
  284. (let ((calcbuf (current-buffer))
  285. (tempbuf (get-buffer-create "*Gnuplot Temp-2*"))
  286. (tempbuftop 1)
  287. (tempoutfile nil)
  288. (calc-graph-curve-num 0)
  289. (calc-graph-refine (and flag (> (prefix-numeric-value flag) 0)))
  290. (recompute (and flag (< (prefix-numeric-value flag) 0)))
  291. (calc-graph-surprise-splot nil)
  292. (tty-output nil)
  293. cache-env calc-graph-is-splot device output calc-graph-resolution precision samples-pos)
  294. (add-hook 'kill-emacs-hook 'calc-graph-kill-hook)
  295. (save-excursion
  296. (calc-graph-init)
  297. (set-buffer tempbuf)
  298. (erase-buffer)
  299. (set-buffer calc-gnuplot-input)
  300. (goto-char (point-min))
  301. (setq calc-graph-is-splot (re-search-forward "^splot[ \t]" nil t))
  302. (let ((str (buffer-string))
  303. (ver calc-gnuplot-version))
  304. (set-buffer (get-buffer-create "*Gnuplot Temp*"))
  305. (erase-buffer)
  306. (insert "# (Note: This is a temporary copy---do not edit!)\n")
  307. (if (>= ver 2)
  308. (insert "set noarrow\nset nolabel\n"
  309. "set autoscale xy\nset nologscale xy\n"
  310. "set xlabel\nset ylabel\nset title\n"
  311. "set noclip points\nset clip one\nset clip two\n"
  312. "set format \"%g\"\nset tics\nset xtics\nset ytics\n"
  313. "set style data linespoints\n"
  314. "set nogrid\nset nokey\nset nopolar\n"))
  315. (if (>= ver 3)
  316. (insert "set surface\nset nocontour\n"
  317. "set " (if calc-graph-is-splot "" "no") "parametric\n"
  318. "set notime\nset border\nset ztics\nset zeroaxis\n"
  319. "set view 60,30,1,1\nset offsets 0,0,0,0\n"))
  320. (setq samples-pos (point))
  321. (insert "\n\n" str))
  322. (goto-char (point-min))
  323. (if calc-graph-is-splot
  324. (if calc-graph-refine
  325. (error "This option works only for 2d plots")
  326. (setq recompute t)))
  327. (let ((calc-gnuplot-input (current-buffer))
  328. (calc-graph-no-auto-view t))
  329. (if printing
  330. (setq device calc-gnuplot-print-device
  331. output calc-gnuplot-print-output)
  332. (setq device (calc-graph-find-command "terminal")
  333. output (calc-graph-find-command "output"))
  334. (or device
  335. (setq device calc-gnuplot-default-device))
  336. (if output
  337. (setq output (car (read-from-string output)))
  338. (setq output calc-gnuplot-default-output)))
  339. (if (or (equal device "") (equal device "default"))
  340. (setq device
  341. (cond
  342. (printing "postscript")
  343. ;; Check MS-Windows before X, in case they have
  344. ;; $DISPLAY set for some reason (e.g., Cygwin or
  345. ;; whatever)
  346. ((string= calc-gnuplot-name "pgnuplot")
  347. "windows")
  348. ((or (eq window-system 'x) (getenv "DISPLAY"))
  349. "x11")
  350. ((>= calc-gnuplot-version 3)
  351. "dumb")
  352. (t "postscript"))))
  353. (if (equal device "dumb")
  354. (setq device (format "dumb %d %d"
  355. (1- (frame-width)) (1- (frame-height)))))
  356. (if (equal device "big")
  357. (setq device (format "dumb %d %d"
  358. (* 4 (- (frame-width) 3))
  359. (* 4 (- (frame-height) 3)))))
  360. (if (stringp output)
  361. (if (or (equal output "auto")
  362. (and (equal output "tty") (setq tty-output t)))
  363. (setq tempoutfile (calc-temp-file-name -1)
  364. output tempoutfile))
  365. (setq output (eval output)))
  366. (or (equal device calc-graph-last-device)
  367. (progn
  368. (setq calc-graph-last-device device)
  369. (calc-gnuplot-command "set terminal" device)))
  370. (or (equal output calc-graph-last-output)
  371. (progn
  372. (setq calc-graph-last-output output)
  373. (calc-gnuplot-command "set output"
  374. (if (equal output "STDOUT")
  375. ""
  376. (prin1-to-string output)))))
  377. (setq calc-graph-resolution (calc-graph-find-command "samples"))
  378. (if calc-graph-resolution
  379. (setq calc-graph-resolution (string-to-number calc-graph-resolution))
  380. (setq calc-graph-resolution (if calc-graph-is-splot
  381. calc-graph-default-resolution-3d
  382. calc-graph-default-resolution)))
  383. (setq precision (calc-graph-find-command "precision"))
  384. (if precision
  385. (setq precision (string-to-number precision))
  386. (setq precision calc-graph-default-precision))
  387. (calc-graph-set-command "terminal")
  388. (calc-graph-set-command "output")
  389. (calc-graph-set-command "samples")
  390. (calc-graph-set-command "precision"))
  391. (goto-char samples-pos)
  392. (insert "set samples " (int-to-string (max (if calc-graph-is-splot 20 200)
  393. (+ 5 calc-graph-resolution))) "\n")
  394. (while (re-search-forward "{\\*[^}]+}[^,\n]*" nil t)
  395. (delete-region (match-beginning 0) (match-end 0))
  396. (if (looking-at ",")
  397. (delete-char 1)
  398. (while (memq (preceding-char) '(?\s ?\t))
  399. (forward-char -1))
  400. (if (eq (preceding-char) ?\,)
  401. (delete-char -1))))
  402. (with-current-buffer calcbuf
  403. (setq cache-env (list calc-angle-mode
  404. calc-complex-mode
  405. calc-simplify-mode
  406. calc-infinite-mode
  407. calc-word-size
  408. precision calc-graph-is-splot))
  409. (if (and (not recompute)
  410. (equal (cdr (car calc-graph-data-cache)) cache-env))
  411. (while (> (length calc-graph-data-cache)
  412. calc-graph-data-cache-limit)
  413. (setcdr calc-graph-data-cache
  414. (cdr (cdr calc-graph-data-cache))))
  415. (setq calc-graph-data-cache (list (cons nil cache-env)))))
  416. (calc-graph-find-plot t t)
  417. (while (re-search-forward
  418. (if calc-graph-is-splot
  419. "{\\([^{}:\n]+\\):\\([^{}:\n]+\\):\\([^{}:\n]+\\)}"
  420. "{\\([^{}:\n]+\\)\\(:\\)\\([^{}:\n]+\\)}")
  421. nil t)
  422. (setq calc-graph-curve-num (1+ calc-graph-curve-num))
  423. (let* ((calc-graph-xname (buffer-substring (match-beginning 1) (match-end 1)))
  424. (xvar (intern (concat "var-" calc-graph-xname)))
  425. (calc-graph-xvalue (math-evaluate-expr (calc-var-value xvar)))
  426. (calc-graph-y3name (and calc-graph-is-splot
  427. (buffer-substring (match-beginning 2)
  428. (match-end 2))))
  429. (y3var (and calc-graph-is-splot (intern (concat "var-" calc-graph-y3name))))
  430. (calc-graph-y3value (and calc-graph-is-splot (calc-var-value y3var)))
  431. (calc-graph-yname (buffer-substring (match-beginning 3) (match-end 3)))
  432. (yvar (intern (concat "var-" calc-graph-yname)))
  433. (calc-graph-yvalue (calc-var-value yvar))
  434. filename)
  435. (delete-region (match-beginning 0) (match-end 0))
  436. (setq filename (calc-temp-file-name calc-graph-curve-num))
  437. (with-current-buffer calcbuf
  438. (let (tempbuftop
  439. (calc-graph-xp calc-graph-xvalue)
  440. (calc-graph-yp calc-graph-yvalue)
  441. (calc-graph-zp nil)
  442. (calc-graph-xlow nil) (calc-graph-xhigh nil) (y3low nil) (y3high nil)
  443. calc-graph-xvec calc-graph-xval calc-graph-xstep var-DUMMY
  444. y3val calc-graph-y3step var-DUMMY2 (calc-graph-zval nil)
  445. calc-graph-yvec calc-graph-yval calc-graph-ycache calc-graph-ycacheptr calc-graph-yvector
  446. calc-graph-numsteps calc-graph-numsteps3
  447. (calc-graph-keep-file (and (not calc-graph-is-splot) (file-exists-p filename)))
  448. (calc-graph-stepcount 0)
  449. (calc-symbolic-mode nil)
  450. (calc-prefer-frac nil)
  451. (calc-internal-prec (max 3 precision))
  452. (calc-simplify-mode (and (not (memq calc-simplify-mode
  453. '(none num)))
  454. calc-simplify-mode))
  455. (calc-graph-blank t)
  456. (calc-graph-non-blank nil)
  457. (math-working-step 0)
  458. (math-working-step-2 nil))
  459. (save-excursion
  460. (if calc-graph-is-splot
  461. (calc-graph-compute-3d)
  462. (calc-graph-compute-2d))
  463. (set-buffer tempbuf)
  464. (goto-char (point-max))
  465. (insert "\n" calc-graph-xname)
  466. (if calc-graph-is-splot
  467. (insert ":" calc-graph-y3name))
  468. (insert ":" calc-graph-yname "\n\n")
  469. (setq tempbuftop (point))
  470. (let ((calc-group-digits nil)
  471. (calc-leading-zeros nil)
  472. (calc-number-radix 10)
  473. (calc-twos-complement-mode nil)
  474. (entry (and (not calc-graph-is-splot)
  475. (list calc-graph-xp calc-graph-yp calc-graph-xhigh calc-graph-numsteps))))
  476. (or (equal entry
  477. (nth 1 (nth (1+ calc-graph-curve-num)
  478. calc-graph-file-cache)))
  479. (setq calc-graph-keep-file nil))
  480. (setcar (cdr (nth (1+ calc-graph-curve-num) calc-graph-file-cache))
  481. entry)
  482. (or calc-graph-keep-file
  483. (calc-graph-format-data)))
  484. (or calc-graph-keep-file
  485. (progn
  486. (or calc-graph-non-blank
  487. (error "No valid data points for %s:%s"
  488. calc-graph-xname calc-graph-yname))
  489. (write-region tempbuftop (point-max) filename
  490. nil 'quiet))))))
  491. (insert (prin1-to-string filename))))
  492. (if calc-graph-surprise-splot
  493. (setcdr cache-env nil))
  494. (if (= calc-graph-curve-num 0)
  495. (progn
  496. (calc-gnuplot-command "clear")
  497. (calc-clear-command-flag 'clear-message)
  498. (message "No data to plot!"))
  499. (setq calc-graph-data-cache-limit (max calc-graph-curve-num
  500. calc-graph-data-cache-limit))
  501. (let ((filename (calc-temp-file-name 0)))
  502. (write-region (point-min) (point-max) filename nil 'quiet)
  503. (calc-gnuplot-command "load" (prin1-to-string filename)))
  504. (or (equal output "STDOUT")
  505. calc-gnuplot-keep-outfile
  506. (progn ; need to close the output file before printing/plotting
  507. (setq calc-graph-last-output "STDOUT")
  508. (calc-gnuplot-command "set output")))
  509. (let ((command (if printing
  510. calc-gnuplot-print-command
  511. (or calc-gnuplot-plot-command
  512. (and (string-match "^dumb" device)
  513. 'calc-graph-show-dumb)
  514. (and tty-output
  515. 'calc-graph-show-tty)))))
  516. (if command
  517. (if (stringp command)
  518. (calc-gnuplot-command
  519. "!" (format command
  520. (or tempoutfile
  521. calc-gnuplot-print-output)))
  522. (if (symbolp command)
  523. (funcall command output)
  524. (eval command))))))))))
  525. (defun calc-graph-compute-2d ()
  526. (if (setq calc-graph-yvec (eq (car-safe calc-graph-yvalue) 'vec))
  527. (if (= (setq calc-graph-numsteps (1- (length calc-graph-yvalue))) 0)
  528. (error "Can't plot an empty vector")
  529. (if (setq calc-graph-xvec (eq (car-safe calc-graph-xvalue) 'vec))
  530. (or (= (1- (length calc-graph-xvalue)) calc-graph-numsteps)
  531. (error "%s and %s have different lengths" calc-graph-xname calc-graph-yname))
  532. (if (and (eq (car-safe calc-graph-xvalue) 'intv)
  533. (math-constp calc-graph-xvalue))
  534. (setq calc-graph-xstep (math-div (math-sub (nth 3 calc-graph-xvalue)
  535. (nth 2 calc-graph-xvalue))
  536. (1- calc-graph-numsteps))
  537. calc-graph-xvalue (nth 2 calc-graph-xvalue))
  538. (if (math-realp calc-graph-xvalue)
  539. (setq calc-graph-xstep 1)
  540. (error "%s is not a suitable basis for %s" calc-graph-xname calc-graph-yname)))))
  541. (or (math-realp calc-graph-yvalue)
  542. (let ((math-arglist nil))
  543. (setq calc-graph-yvalue (math-evaluate-expr calc-graph-yvalue))
  544. (calc-default-formula-arglist calc-graph-yvalue)
  545. (or math-arglist
  546. (error "%s does not contain any unassigned variables" calc-graph-yname))
  547. (and (cdr math-arglist)
  548. (error "%s contains more than one variable: %s"
  549. calc-graph-yname math-arglist))
  550. (setq calc-graph-yvalue (math-expr-subst calc-graph-yvalue
  551. (math-build-var-name (car math-arglist))
  552. '(var DUMMY var-DUMMY)))))
  553. (setq calc-graph-ycache (assoc calc-graph-yvalue calc-graph-data-cache))
  554. (delq calc-graph-ycache calc-graph-data-cache)
  555. (nconc calc-graph-data-cache
  556. (list (or calc-graph-ycache (setq calc-graph-ycache (list calc-graph-yvalue)))))
  557. (if (and (not (setq calc-graph-xvec (eq (car-safe calc-graph-xvalue) 'vec)))
  558. calc-graph-refine (cdr (cdr calc-graph-ycache)))
  559. (calc-graph-refine-2d)
  560. (calc-graph-recompute-2d))))
  561. (defun calc-graph-refine-2d ()
  562. (setq calc-graph-keep-file nil
  563. calc-graph-ycacheptr (cdr calc-graph-ycache))
  564. (if (and (setq calc-graph-xval (calc-graph-find-command "xrange"))
  565. (string-match "\\`\\[\\([0-9.eE+-]*\\):\\([0-9.eE+-]*\\)\\]\\'"
  566. calc-graph-xval))
  567. (let ((b2 (match-beginning 2))
  568. (e2 (match-end 2)))
  569. (setq calc-graph-xlow (math-read-number (substring calc-graph-xval
  570. (match-beginning 1)
  571. (match-end 1)))
  572. calc-graph-xhigh (math-read-number (substring calc-graph-xval b2 e2))))
  573. (if calc-graph-xlow
  574. (while (and (cdr calc-graph-ycacheptr)
  575. (Math-lessp (car (nth 1 calc-graph-ycacheptr)) calc-graph-xlow))
  576. (setq calc-graph-ycacheptr (cdr calc-graph-ycacheptr)))))
  577. (setq math-working-step-2 (1- (length calc-graph-ycacheptr)))
  578. (while (and (cdr calc-graph-ycacheptr)
  579. (or (not calc-graph-xhigh)
  580. (Math-lessp (car (car calc-graph-ycacheptr)) calc-graph-xhigh)))
  581. (setq var-DUMMY (math-div (math-add (car (car calc-graph-ycacheptr))
  582. (car (nth 1 calc-graph-ycacheptr)))
  583. 2)
  584. math-working-step (1+ math-working-step)
  585. calc-graph-yval (math-evaluate-expr calc-graph-yvalue))
  586. (setcdr calc-graph-ycacheptr (cons (cons var-DUMMY calc-graph-yval)
  587. (cdr calc-graph-ycacheptr)))
  588. (setq calc-graph-ycacheptr (cdr (cdr calc-graph-ycacheptr))))
  589. (setq calc-graph-yp calc-graph-ycache
  590. calc-graph-numsteps 1000000))
  591. (defun calc-graph-recompute-2d ()
  592. (setq calc-graph-ycacheptr calc-graph-ycache)
  593. (if calc-graph-xvec
  594. (setq calc-graph-numsteps (1- (length calc-graph-xvalue))
  595. calc-graph-yvector nil)
  596. (if (and (eq (car-safe calc-graph-xvalue) 'intv)
  597. (math-constp calc-graph-xvalue))
  598. (setq calc-graph-numsteps calc-graph-resolution
  599. calc-graph-yp nil
  600. calc-graph-xlow (nth 2 calc-graph-xvalue)
  601. calc-graph-xhigh (nth 3 calc-graph-xvalue)
  602. calc-graph-xstep (math-div (math-sub calc-graph-xhigh calc-graph-xlow)
  603. (1- calc-graph-numsteps))
  604. calc-graph-xvalue (nth 2 calc-graph-xvalue))
  605. (error "%s is not a suitable basis for %s"
  606. calc-graph-xname calc-graph-yname)))
  607. (setq math-working-step-2 calc-graph-numsteps)
  608. (while (>= (setq calc-graph-numsteps (1- calc-graph-numsteps)) 0)
  609. (setq math-working-step (1+ math-working-step))
  610. (if calc-graph-xvec
  611. (progn
  612. (setq calc-graph-xp (cdr calc-graph-xp)
  613. calc-graph-xval (car calc-graph-xp))
  614. (and (not (eq calc-graph-ycacheptr calc-graph-ycache))
  615. (consp (car calc-graph-ycacheptr))
  616. (not (Math-lessp (car (car calc-graph-ycacheptr)) calc-graph-xval))
  617. (setq calc-graph-ycacheptr calc-graph-ycache)))
  618. (if (= calc-graph-numsteps 0)
  619. (setq calc-graph-xval calc-graph-xhigh) ; avoid cumulative roundoff
  620. (setq calc-graph-xval calc-graph-xvalue
  621. calc-graph-xvalue (math-add calc-graph-xvalue calc-graph-xstep))))
  622. (while (and (cdr calc-graph-ycacheptr)
  623. (Math-lessp (car (nth 1 calc-graph-ycacheptr)) calc-graph-xval))
  624. (setq calc-graph-ycacheptr (cdr calc-graph-ycacheptr)))
  625. (or (and (cdr calc-graph-ycacheptr)
  626. (Math-equal (car (nth 1 calc-graph-ycacheptr)) calc-graph-xval))
  627. (progn
  628. (setq calc-graph-keep-file nil
  629. var-DUMMY calc-graph-xval)
  630. (setcdr calc-graph-ycacheptr (cons (cons calc-graph-xval (math-evaluate-expr calc-graph-yvalue))
  631. (cdr calc-graph-ycacheptr)))))
  632. (setq calc-graph-ycacheptr (cdr calc-graph-ycacheptr))
  633. (if calc-graph-xvec
  634. (setq calc-graph-yvector (cons (cdr (car calc-graph-ycacheptr)) calc-graph-yvector))
  635. (or calc-graph-yp (setq calc-graph-yp calc-graph-ycacheptr))))
  636. (if calc-graph-xvec
  637. (setq calc-graph-xp calc-graph-xvalue
  638. calc-graph-yvec t
  639. calc-graph-yp (cons 'vec (nreverse calc-graph-yvector))
  640. calc-graph-numsteps (1- (length calc-graph-xp)))
  641. (setq calc-graph-numsteps 1000000)))
  642. (defun calc-graph-compute-3d ()
  643. (if (setq calc-graph-yvec (eq (car-safe calc-graph-yvalue) 'vec))
  644. (if (math-matrixp calc-graph-yvalue)
  645. (progn
  646. (setq calc-graph-numsteps (1- (length calc-graph-yvalue))
  647. calc-graph-numsteps3 (1- (length (nth 1 calc-graph-yvalue))))
  648. (if (eq (car-safe calc-graph-xvalue) 'vec)
  649. (or (= (1- (length calc-graph-xvalue)) calc-graph-numsteps)
  650. (error "%s has wrong length" calc-graph-xname))
  651. (if (and (eq (car-safe calc-graph-xvalue) 'intv)
  652. (math-constp calc-graph-xvalue))
  653. (setq calc-graph-xvalue (calcFunc-index calc-graph-numsteps
  654. (nth 2 calc-graph-xvalue)
  655. (math-div
  656. (math-sub (nth 3 calc-graph-xvalue)
  657. (nth 2 calc-graph-xvalue))
  658. (1- calc-graph-numsteps))))
  659. (if (math-realp calc-graph-xvalue)
  660. (setq calc-graph-xvalue (calcFunc-index calc-graph-numsteps calc-graph-xvalue 1))
  661. (error "%s is not a suitable basis for %s" calc-graph-xname calc-graph-yname))))
  662. (if (eq (car-safe calc-graph-y3value) 'vec)
  663. (or (= (1- (length calc-graph-y3value)) calc-graph-numsteps3)
  664. (error "%s has wrong length" calc-graph-y3name))
  665. (if (and (eq (car-safe calc-graph-y3value) 'intv)
  666. (math-constp calc-graph-y3value))
  667. (setq calc-graph-y3value (calcFunc-index calc-graph-numsteps3
  668. (nth 2 calc-graph-y3value)
  669. (math-div
  670. (math-sub (nth 3 calc-graph-y3value)
  671. (nth 2 calc-graph-y3value))
  672. (1- calc-graph-numsteps3))))
  673. (if (math-realp calc-graph-y3value)
  674. (setq calc-graph-y3value (calcFunc-index calc-graph-numsteps3 calc-graph-y3value 1))
  675. (error "%s is not a suitable basis for %s" calc-graph-y3name calc-graph-yname))))
  676. (setq calc-graph-xp nil
  677. calc-graph-yp nil
  678. calc-graph-zp nil
  679. calc-graph-xvec t)
  680. (while (setq calc-graph-xvalue (cdr calc-graph-xvalue) calc-graph-yvalue (cdr calc-graph-yvalue))
  681. (setq calc-graph-xp (nconc calc-graph-xp (make-list (1+ calc-graph-numsteps3) (car calc-graph-xvalue)))
  682. calc-graph-yp (nconc calc-graph-yp (cons 0 (copy-sequence (cdr calc-graph-y3value))))
  683. calc-graph-zp (nconc calc-graph-zp (cons '(skip)
  684. (copy-sequence (cdr (car calc-graph-yvalue)))))))
  685. (setq calc-graph-numsteps (1- (* calc-graph-numsteps
  686. (1+ calc-graph-numsteps3)))))
  687. (if (= (setq calc-graph-numsteps (1- (length calc-graph-yvalue))) 0)
  688. (error "Can't plot an empty vector"))
  689. (or (and (eq (car-safe calc-graph-xvalue) 'vec)
  690. (= (1- (length calc-graph-xvalue)) calc-graph-numsteps))
  691. (error "%s is not a suitable basis for %s" calc-graph-xname calc-graph-yname))
  692. (or (and (eq (car-safe calc-graph-y3value) 'vec)
  693. (= (1- (length calc-graph-y3value)) calc-graph-numsteps))
  694. (error "%s is not a suitable basis for %s" calc-graph-y3name calc-graph-yname))
  695. (setq calc-graph-xp calc-graph-xvalue
  696. calc-graph-yp calc-graph-y3value
  697. calc-graph-zp calc-graph-yvalue
  698. calc-graph-xvec t))
  699. (or (math-realp calc-graph-yvalue)
  700. (let ((math-arglist nil))
  701. (setq calc-graph-yvalue (math-evaluate-expr calc-graph-yvalue))
  702. (calc-default-formula-arglist calc-graph-yvalue)
  703. (setq math-arglist (sort math-arglist 'string-lessp))
  704. (or (cdr math-arglist)
  705. (error "%s does not contain enough unassigned variables" calc-graph-yname))
  706. (and (cdr (cdr math-arglist))
  707. (error "%s contains too many variables: %s" calc-graph-yname math-arglist))
  708. (setq calc-graph-yvalue (math-multi-subst calc-graph-yvalue
  709. (mapcar 'math-build-var-name
  710. math-arglist)
  711. '((var DUMMY var-DUMMY)
  712. (var DUMMY2 var-DUMMY2))))))
  713. (if (setq calc-graph-xvec (eq (car-safe calc-graph-xvalue) 'vec))
  714. (setq calc-graph-numsteps (1- (length calc-graph-xvalue)))
  715. (if (and (eq (car-safe calc-graph-xvalue) 'intv)
  716. (math-constp calc-graph-xvalue))
  717. (setq calc-graph-numsteps calc-graph-resolution
  718. calc-graph-xvalue (calcFunc-index calc-graph-numsteps
  719. (nth 2 calc-graph-xvalue)
  720. (math-div (math-sub (nth 3 calc-graph-xvalue)
  721. (nth 2 calc-graph-xvalue))
  722. (1- calc-graph-numsteps))))
  723. (error "%s is not a suitable basis for %s"
  724. calc-graph-xname calc-graph-yname)))
  725. (if (eq (car-safe calc-graph-y3value) 'vec)
  726. (setq calc-graph-numsteps3 (1- (length calc-graph-y3value)))
  727. (if (and (eq (car-safe calc-graph-y3value) 'intv)
  728. (math-constp calc-graph-y3value))
  729. (setq calc-graph-numsteps3 calc-graph-resolution
  730. calc-graph-y3value (calcFunc-index calc-graph-numsteps3
  731. (nth 2 calc-graph-y3value)
  732. (math-div (math-sub (nth 3 calc-graph-y3value)
  733. (nth 2 calc-graph-y3value))
  734. (1- calc-graph-numsteps3))))
  735. (error "%s is not a suitable basis for %s"
  736. calc-graph-y3name calc-graph-yname)))
  737. (setq calc-graph-xp nil
  738. calc-graph-yp nil
  739. calc-graph-zp nil
  740. calc-graph-xvec t)
  741. (setq math-working-step 0)
  742. (while (setq calc-graph-xvalue (cdr calc-graph-xvalue))
  743. (setq calc-graph-xp (nconc calc-graph-xp (make-list (1+ calc-graph-numsteps3) (car calc-graph-xvalue)))
  744. calc-graph-yp (nconc calc-graph-yp (cons 0 (copy-sequence (cdr calc-graph-y3value))))
  745. calc-graph-zp (cons '(skip) calc-graph-zp)
  746. calc-graph-y3step calc-graph-y3value
  747. var-DUMMY (car calc-graph-xvalue)
  748. math-working-step-2 0
  749. math-working-step (1+ math-working-step))
  750. (while (setq calc-graph-y3step (cdr calc-graph-y3step))
  751. (setq math-working-step-2 (1+ math-working-step-2)
  752. var-DUMMY2 (car calc-graph-y3step)
  753. calc-graph-zp (cons (math-evaluate-expr calc-graph-yvalue) calc-graph-zp))))
  754. (setq calc-graph-zp (nreverse calc-graph-zp)
  755. calc-graph-numsteps (1- (* calc-graph-numsteps (1+ calc-graph-numsteps3))))))
  756. (defun calc-graph-format-data ()
  757. (if (math-contains-sdev-p calc-graph-yp)
  758. (let ((yp calc-graph-yp))
  759. (setq calc-graph-yp (cons 'vec (mapcar 'math-get-value (cdr yp))))
  760. (setq calc-graph-zp (cons 'vec (mapcar 'math-get-sdev (cdr yp))))))
  761. (while (<= (setq calc-graph-stepcount (1+ calc-graph-stepcount)) calc-graph-numsteps)
  762. (if calc-graph-xvec
  763. (setq calc-graph-xp (cdr calc-graph-xp)
  764. calc-graph-xval (car calc-graph-xp)
  765. calc-graph-yp (cdr calc-graph-yp)
  766. calc-graph-yval (car calc-graph-yp)
  767. calc-graph-zp (cdr calc-graph-zp)
  768. calc-graph-zval (car calc-graph-zp))
  769. (if calc-graph-yvec
  770. (setq calc-graph-xval calc-graph-xvalue
  771. calc-graph-xvalue (math-add calc-graph-xvalue calc-graph-xstep)
  772. calc-graph-yp (cdr calc-graph-yp)
  773. calc-graph-yval (car calc-graph-yp))
  774. (setq calc-graph-xval (car (car calc-graph-yp))
  775. calc-graph-yval (cdr (car calc-graph-yp))
  776. calc-graph-yp (cdr calc-graph-yp))
  777. (if (or (not calc-graph-yp)
  778. (and calc-graph-xhigh (equal calc-graph-xval calc-graph-xhigh)))
  779. (setq calc-graph-numsteps 0))))
  780. (if calc-graph-is-splot
  781. (if (and (eq (car-safe calc-graph-zval) 'calcFunc-xyz)
  782. (= (length calc-graph-zval) 4))
  783. (setq calc-graph-xval (nth 1 calc-graph-zval)
  784. calc-graph-yval (nth 2 calc-graph-zval)
  785. calc-graph-zval (nth 3 calc-graph-zval)))
  786. (if (and (eq (car-safe calc-graph-yval) 'calcFunc-xyz)
  787. (= (length calc-graph-yval) 4))
  788. (progn
  789. (or calc-graph-surprise-splot
  790. (with-current-buffer (get-buffer-create "*Gnuplot Temp*")
  791. (save-excursion
  792. (goto-char (point-max))
  793. (re-search-backward "^plot[ \t]")
  794. (insert "set parametric\ns")
  795. (setq calc-graph-surprise-splot t))))
  796. (setq calc-graph-xval (nth 1 calc-graph-yval)
  797. calc-graph-zval (nth 3 calc-graph-yval)
  798. calc-graph-yval (nth 2 calc-graph-yval)))
  799. (if (and (eq (car-safe calc-graph-yval) 'calcFunc-xy)
  800. (= (length calc-graph-yval) 3))
  801. (setq calc-graph-xval (nth 1 calc-graph-yval)
  802. calc-graph-yval (nth 2 calc-graph-yval)))))
  803. (if (and (Math-realp calc-graph-xval)
  804. (Math-realp calc-graph-yval)
  805. (or (not calc-graph-zval) (Math-realp calc-graph-zval)))
  806. (progn
  807. (setq calc-graph-blank nil
  808. calc-graph-non-blank t)
  809. (if (Math-integerp calc-graph-xval)
  810. (insert (math-format-number calc-graph-xval))
  811. (if (eq (car calc-graph-xval) 'frac)
  812. (setq calc-graph-xval (math-float calc-graph-xval)))
  813. (insert (math-format-number (nth 1 calc-graph-xval))
  814. "e" (int-to-string (nth 2 calc-graph-xval))))
  815. (insert " ")
  816. (if (Math-integerp calc-graph-yval)
  817. (insert (math-format-number calc-graph-yval))
  818. (if (eq (car calc-graph-yval) 'frac)
  819. (setq calc-graph-yval (math-float calc-graph-yval)))
  820. (insert (math-format-number (nth 1 calc-graph-yval))
  821. "e" (int-to-string (nth 2 calc-graph-yval))))
  822. (if calc-graph-zval
  823. (progn
  824. (insert " ")
  825. (if (Math-integerp calc-graph-zval)
  826. (insert (math-format-number calc-graph-zval))
  827. (if (eq (car calc-graph-zval) 'frac)
  828. (setq calc-graph-zval (math-float calc-graph-zval)))
  829. (insert (math-format-number (nth 1 calc-graph-zval))
  830. "e" (int-to-string (nth 2 calc-graph-zval))))))
  831. (insert "\n"))
  832. (and (not (equal calc-graph-zval '(skip)))
  833. (boundp 'var-PlotRejects)
  834. (eq (car-safe var-PlotRejects) 'vec)
  835. (nconc var-PlotRejects
  836. (list (list 'vec
  837. calc-graph-curve-num
  838. calc-graph-stepcount
  839. calc-graph-xval calc-graph-yval)))
  840. (calc-refresh-evaltos 'var-PlotRejects))
  841. (or calc-graph-blank
  842. (progn
  843. (insert "\n")
  844. (setq calc-graph-blank t))))))
  845. (defun calc-temp-file-name (num)
  846. (while (<= (length calc-graph-file-cache) (1+ num))
  847. (setq calc-graph-file-cache (nconc calc-graph-file-cache (list nil))))
  848. (car (or (nth (1+ num) calc-graph-file-cache)
  849. (setcar (nthcdr (1+ num) calc-graph-file-cache)
  850. (list (make-temp-file
  851. (concat calc-gnuplot-tempfile
  852. (if (<= num 0)
  853. (char-to-string (- ?A num))
  854. (int-to-string num))))
  855. nil)))))
  856. (defun calc-graph-delete-temps ()
  857. (while calc-graph-file-cache
  858. (and (car calc-graph-file-cache)
  859. (file-exists-p (car (car calc-graph-file-cache)))
  860. (condition-case err
  861. (delete-file (car (car calc-graph-file-cache)))
  862. (error nil)))
  863. (setq calc-graph-file-cache (cdr calc-graph-file-cache))))
  864. (defun calc-graph-kill-hook ()
  865. (calc-graph-delete-temps))
  866. (defun calc-graph-show-tty (output)
  867. "Default calc-gnuplot-plot-command for \"tty\" output mode.
  868. This is useful for tek40xx and other graphics-terminal types."
  869. (call-process shell-file-name nil calc-gnuplot-buffer nil
  870. shell-command-switch
  871. (format "cat %s >/dev/tty; rm %s" output output)))
  872. (defvar calc-dumb-map nil
  873. "The keymap for the \"dumb\" terminal plot.")
  874. (defun calc-graph-show-dumb (&optional output)
  875. "Default calc-gnuplot-plot-command for Pinard's \"dumb\" terminal type.
  876. This \"dumb\" driver will be present in Gnuplot 3.0."
  877. (interactive)
  878. (save-window-excursion
  879. (switch-to-buffer calc-gnuplot-buffer)
  880. (delete-other-windows)
  881. (goto-char calc-gnuplot-trail-mark)
  882. (or (search-forward "\f" nil t)
  883. (sleep-for 1))
  884. (goto-char (point-max))
  885. (re-search-backward "\f\\|^[ \t]+\\^$\\|G N U P L O T")
  886. (if (looking-at "\f")
  887. (progn
  888. (forward-char 1)
  889. (if (eolp) (forward-line 1))
  890. (or (calc-graph-find-command "time")
  891. (calc-graph-find-command "title")
  892. (calc-graph-find-command "ylabel")
  893. (let ((pt (point)))
  894. (insert-before-markers (format "(%s)" (current-time-string)))
  895. (goto-char pt)))
  896. (set-window-start (selected-window) (point))
  897. (goto-char (point-max)))
  898. (end-of-line)
  899. (backward-char 1)
  900. (recenter '(4)))
  901. (or calc-dumb-map
  902. (progn
  903. (setq calc-dumb-map (make-sparse-keymap))
  904. (define-key calc-dumb-map "\n" 'scroll-up-command)
  905. (define-key calc-dumb-map " " 'scroll-up-command)
  906. (define-key calc-dumb-map [?\S-\ ] 'scroll-down-command)
  907. (define-key calc-dumb-map "\177" 'scroll-down-command)
  908. (define-key calc-dumb-map "<" 'scroll-left)
  909. (define-key calc-dumb-map ">" 'scroll-right)
  910. (define-key calc-dumb-map "{" 'scroll-down-command)
  911. (define-key calc-dumb-map "}" 'scroll-up-command)
  912. (define-key calc-dumb-map "q" 'exit-recursive-edit)
  913. (define-key calc-dumb-map "\C-c\C-c" 'exit-recursive-edit)))
  914. (use-local-map calc-dumb-map)
  915. (setq truncate-lines t)
  916. (message "Type `q' or `C-c C-c' to return to Calc")
  917. (recursive-edit)
  918. (bury-buffer "*Gnuplot Trail*")))
  919. (defun calc-graph-clear ()
  920. (interactive)
  921. (if calc-graph-last-device
  922. (if (or (equal calc-graph-last-device "x11")
  923. (equal calc-graph-last-device "X11"))
  924. (calc-gnuplot-command "set output"
  925. (if (equal calc-graph-last-output "STDOUT")
  926. ""
  927. (prin1-to-string calc-graph-last-output)))
  928. (calc-gnuplot-command "clear"))))
  929. (defun calc-graph-title-x (title)
  930. (interactive "sX axis title: ")
  931. (calc-graph-set-command "xlabel" (if (not (equal title ""))
  932. (prin1-to-string title))))
  933. (defun calc-graph-title-y (title)
  934. (interactive "sY axis title: ")
  935. (calc-graph-set-command "ylabel" (if (not (equal title ""))
  936. (prin1-to-string title))))
  937. (defun calc-graph-title-z (title)
  938. (interactive "sZ axis title: ")
  939. (calc-graph-set-command "zlabel" (if (not (equal title ""))
  940. (prin1-to-string title))))
  941. (defun calc-graph-range-x (range)
  942. (interactive "sX axis range: ")
  943. (calc-graph-set-range "xrange" range))
  944. (defun calc-graph-range-y (range)
  945. (interactive "sY axis range: ")
  946. (calc-graph-set-range "yrange" range))
  947. (defun calc-graph-range-z (range)
  948. (interactive "sZ axis range: ")
  949. (calc-graph-set-range "zrange" range))
  950. (defun calc-graph-set-range (cmd range)
  951. (if (equal range "$")
  952. (calc-wrapper
  953. (let ((val (calc-top-n 1)))
  954. (if (and (eq (car-safe val) 'intv) (math-constp val))
  955. (setq range (concat
  956. (math-format-number (math-float (nth 2 val))) ":"
  957. (math-format-number (math-float (nth 3 val)))))
  958. (if (and (eq (car-safe val) 'vec)
  959. (= (length val) 3))
  960. (setq range (concat
  961. (math-format-number (math-float (nth 1 val))) ":"
  962. (math-format-number (math-float (nth 2 val)))))
  963. (error "Range specification must be an interval or 2-vector")))
  964. (calc-pop-stack 1))))
  965. (if (string-match "\\[.+\\]" range)
  966. (setq range (substring range 1 -1)))
  967. (if (and (not (string-match ":" range))
  968. (or (string-match "," range)
  969. (string-match " " range)))
  970. (aset range (match-beginning 0) ?\:))
  971. (calc-graph-set-command cmd (if (not (equal range ""))
  972. (concat "[" range "]"))))
  973. (defun calc-graph-log-x (flag)
  974. (interactive "P")
  975. (calc-graph-set-log flag 0 0))
  976. (defun calc-graph-log-y (flag)
  977. (interactive "P")
  978. (calc-graph-set-log 0 flag 0))
  979. (defun calc-graph-log-z (flag)
  980. (interactive "P")
  981. (calc-graph-set-log 0 0 flag))
  982. (defun calc-graph-set-log (xflag yflag zflag)
  983. (let* ((old (or (calc-graph-find-command "logscale") ""))
  984. (xold (string-match "x" old))
  985. (yold (string-match "y" old))
  986. (zold (string-match "z" old))
  987. str)
  988. (setq str (concat (if (if xflag
  989. (if (eq xflag 0) xold
  990. (> (prefix-numeric-value xflag) 0))
  991. (not xold)) "x" "")
  992. (if (if yflag
  993. (if (eq yflag 0) yold
  994. (> (prefix-numeric-value yflag) 0))
  995. (not yold)) "y" "")
  996. (if (if zflag
  997. (if (eq zflag 0) zold
  998. (> (prefix-numeric-value zflag) 0))
  999. (not zold)) "z" "")))
  1000. (calc-graph-set-command "logscale" (if (not (equal str "")) str))))
  1001. (defun calc-graph-line-style (style)
  1002. (interactive "P")
  1003. (calc-graph-set-styles (and style (prefix-numeric-value style)) t))
  1004. (defun calc-graph-point-style (style)
  1005. (interactive "P")
  1006. (calc-graph-set-styles t (and style (prefix-numeric-value style))))
  1007. (defun calc-graph-set-styles (lines points &optional yerr)
  1008. (calc-graph-init)
  1009. (with-current-buffer calc-gnuplot-input
  1010. (or (calc-graph-find-plot nil nil)
  1011. (error "No data points have been set!"))
  1012. (let ((base (point))
  1013. (mode nil) (lstyle nil) (pstyle nil)
  1014. start end lenbl penbl errform)
  1015. (re-search-forward "[,\n]")
  1016. (forward-char -1)
  1017. (setq end (point) start end)
  1018. (goto-char base)
  1019. (if (looking-at "[^,\n]*[^,\n \t]\\([ \t]+with\\)")
  1020. (progn
  1021. (setq start (match-beginning 1))
  1022. (goto-char (match-end 0))
  1023. (if (looking-at "[ \t]+\\([a-z]+\\)")
  1024. (setq mode (buffer-substring (match-beginning 1)
  1025. (match-end 1))))
  1026. (if (looking-at "[ \ta-z]+\\([0-9]+\\)")
  1027. (setq lstyle (string-to-number
  1028. (buffer-substring (match-beginning 1)
  1029. (match-end 1)))))
  1030. (if (looking-at "[ \ta-z]+[0-9]+[ \t]+\\([0-9]+\\)")
  1031. (setq pstyle (string-to-number
  1032. (buffer-substring (match-beginning 1)
  1033. (match-end 1)))))))
  1034. (unless yerr
  1035. (setq lenbl (or (equal mode "lines")
  1036. (equal mode "linespoints"))
  1037. penbl (or (equal mode "points")
  1038. (equal mode "linespoints")))
  1039. (if lines
  1040. (or (eq lines t)
  1041. (setq lstyle lines
  1042. lenbl (>= lines 0)))
  1043. (setq lenbl (not lenbl)))
  1044. (if points
  1045. (or (eq points t)
  1046. (setq pstyle points
  1047. penbl (>= points 0)))
  1048. (setq penbl (not penbl))))
  1049. (delete-region start end)
  1050. (goto-char start)
  1051. (setq errform
  1052. (condition-case nil
  1053. (math-contains-sdev-p
  1054. (eval (intern
  1055. (concat "var-"
  1056. (save-excursion
  1057. (re-search-backward ":\\(.*\\)\\}")
  1058. (match-string 1))))))
  1059. (error nil)))
  1060. (if yerr
  1061. (insert " with yerrorbars")
  1062. (insert " with "
  1063. (if (and errform
  1064. (equal mode "dots")
  1065. (eq lines t))
  1066. "yerrorbars"
  1067. (if lenbl
  1068. (if penbl "linespoints" "lines")
  1069. (if penbl "points" "dots"))))
  1070. (if (and pstyle (> pstyle 0))
  1071. (insert " "
  1072. (if (and lstyle (> lstyle 0)) (int-to-string lstyle) "1")
  1073. " " (int-to-string pstyle))
  1074. (if (and lstyle (> lstyle 0))
  1075. (insert " " (int-to-string lstyle)))))))
  1076. (calc-graph-view-commands))
  1077. (defun calc-graph-zero-x (flag)
  1078. (interactive "P")
  1079. (calc-graph-set-command "noxzeroaxis"
  1080. (and (if flag
  1081. (<= (prefix-numeric-value flag) 0)
  1082. (not (calc-graph-find-command "noxzeroaxis")))
  1083. " ")))
  1084. (defun calc-graph-zero-y (flag)
  1085. (interactive "P")
  1086. (calc-graph-set-command "noyzeroaxis"
  1087. (and (if flag
  1088. (<= (prefix-numeric-value flag) 0)
  1089. (not (calc-graph-find-command "noyzeroaxis")))
  1090. " ")))
  1091. (defun calc-graph-name (name)
  1092. (interactive "sTitle for current curve: ")
  1093. (calc-graph-init)
  1094. (with-current-buffer calc-gnuplot-input
  1095. (or (calc-graph-find-plot nil nil)
  1096. (error "No data points have been set!"))
  1097. (let ((base (point))
  1098. start
  1099. end)
  1100. (re-search-forward "[,\n]\\|[ \t]+with")
  1101. (setq end (match-beginning 0))
  1102. (goto-char base)
  1103. (if (looking-at "[^,\n]*[^,\n \t]\\([ \t]+title\\)")
  1104. (progn
  1105. (goto-char (match-beginning 1))
  1106. (delete-region (point) end))
  1107. (goto-char end))
  1108. (insert " title " (prin1-to-string name))))
  1109. (calc-graph-view-commands))
  1110. (defun calc-graph-hide (flag)
  1111. (interactive "P")
  1112. (calc-graph-init)
  1113. (and (calc-graph-find-plot nil nil)
  1114. (progn
  1115. (or (looking-at "{")
  1116. (error "Can't hide this curve (wrong format)"))
  1117. (forward-char 1)
  1118. (if (looking-at "*")
  1119. (if (or (null flag) (<= (prefix-numeric-value flag) 0))
  1120. (delete-char 1))
  1121. (if (or (null flag) (> (prefix-numeric-value flag) 0))
  1122. (insert "*"))))))
  1123. (defun calc-graph-header (title)
  1124. (interactive "sTitle for entire graph: ")
  1125. (calc-graph-set-command "title" (if (not (equal title ""))
  1126. (prin1-to-string title))))
  1127. (defun calc-graph-border (flag)
  1128. (interactive "P")
  1129. (calc-graph-set-command "noborder"
  1130. (and (if flag
  1131. (<= (prefix-numeric-value flag) 0)
  1132. (not (calc-graph-find-command "noborder")))
  1133. " ")))
  1134. (defun calc-graph-grid (flag)
  1135. (interactive "P")
  1136. (calc-graph-set-command "grid" (and (if flag
  1137. (> (prefix-numeric-value flag) 0)
  1138. (not (calc-graph-find-command "grid")))
  1139. " ")))
  1140. (defun calc-graph-key (flag)
  1141. (interactive "P")
  1142. (calc-graph-set-command "key" (and (if flag
  1143. (> (prefix-numeric-value flag) 0)
  1144. (not (calc-graph-find-command "key")))
  1145. " ")))
  1146. (defun calc-graph-num-points (res flag)
  1147. (interactive "sNumber of data points: \nP")
  1148. (if flag
  1149. (if (> (prefix-numeric-value flag) 0)
  1150. (if (equal res "")
  1151. (message "Default resolution is %d"
  1152. calc-graph-default-resolution)
  1153. (setq calc-graph-default-resolution (string-to-number res)))
  1154. (if (equal res "")
  1155. (message "Default 3D resolution is %d"
  1156. calc-graph-default-resolution-3d)
  1157. (setq calc-graph-default-resolution-3d (string-to-number res))))
  1158. (calc-graph-set-command "samples" (if (not (equal res "")) res))))
  1159. (defun calc-graph-device (name flag)
  1160. (interactive "sDevice name: \nP")
  1161. (if (equal name "?")
  1162. (progn
  1163. (calc-gnuplot-command "set terminal")
  1164. (calc-graph-view-trail))
  1165. (if flag
  1166. (if (> (prefix-numeric-value flag) 0)
  1167. (if (equal name "")
  1168. (message "Default GNUPLOT device is \"%s\""
  1169. calc-gnuplot-default-device)
  1170. (setq calc-gnuplot-default-device name))
  1171. (if (equal name "")
  1172. (message "GNUPLOT device for Print command is \"%s\""
  1173. calc-gnuplot-print-device)
  1174. (setq calc-gnuplot-print-device name)))
  1175. (calc-graph-set-command "terminal" (if (not (equal name ""))
  1176. name)))))
  1177. (defun calc-graph-output (name flag)
  1178. (interactive "FOutput file name: \np")
  1179. (cond ((string-match "\\<[aA][uU][tT][oO]$" name)
  1180. (setq name "auto"))
  1181. ((string-match "\\<[tT][tT][yY]$" name)
  1182. (setq name "tty"))
  1183. ((string-match "\\<[sS][tT][dD][oO][uU][tT]$" name)
  1184. (setq name "STDOUT"))
  1185. ((equal (file-name-nondirectory name) "")
  1186. (setq name ""))
  1187. (t (setq name (expand-file-name name))))
  1188. (if flag
  1189. (if (> (prefix-numeric-value flag) 0)
  1190. (if (equal name "")
  1191. (message "Default GNUPLOT output file is \"%s\""
  1192. calc-gnuplot-default-output)
  1193. (setq calc-gnuplot-default-output name))
  1194. (if (equal name "")
  1195. (message "GNUPLOT output file for Print command is \"%s\""
  1196. calc-gnuplot-print-output)
  1197. (setq calc-gnuplot-print-output name)))
  1198. (calc-graph-set-command "output" (if (not (equal name ""))
  1199. (prin1-to-string name)))))
  1200. (defun calc-graph-display (name)
  1201. (interactive "sX display name: ")
  1202. (if (equal name "")
  1203. (message "Current X display is \"%s\""
  1204. (or calc-gnuplot-display "<none>"))
  1205. (setq calc-gnuplot-display name)
  1206. (if (calc-gnuplot-alive)
  1207. (calc-gnuplot-command "exit"))))
  1208. (defun calc-graph-geometry (name)
  1209. (interactive "sX geometry spec (or \"default\"): ")
  1210. (if (equal name "")
  1211. (message "Current X geometry is \"%s\""
  1212. (or calc-gnuplot-geometry "default"))
  1213. (setq calc-gnuplot-geometry (and (not (equal name "default")) name))
  1214. (if (calc-gnuplot-alive)
  1215. (calc-gnuplot-command "exit"))))
  1216. (defun calc-graph-find-command (cmd)
  1217. (calc-graph-init)
  1218. (with-current-buffer calc-gnuplot-input
  1219. (goto-char (point-min))
  1220. (if (re-search-forward (concat "^set[ \t]+" cmd "[ \t]*\\(.*\\)$") nil t)
  1221. (buffer-substring (match-beginning 1) (match-end 1)))))
  1222. (defun calc-graph-set-command (cmd &rest args)
  1223. (calc-graph-init)
  1224. (with-current-buffer calc-gnuplot-input
  1225. (goto-char (point-min))
  1226. (if (re-search-forward (concat "^set[ \t]+" cmd "[ \t\n]") nil t)
  1227. (progn
  1228. (forward-char -1)
  1229. (end-of-line)
  1230. (let ((end (point)))
  1231. (beginning-of-line)
  1232. (delete-region (point) (1+ end))))
  1233. (if (calc-graph-find-plot t t)
  1234. (if (eq (preceding-char) ?\n)
  1235. (forward-char -1))
  1236. (goto-char (1- (point-max)))))
  1237. (if (and args (car args))
  1238. (progn
  1239. (or (bolp)
  1240. (insert "\n"))
  1241. (insert "set " (mapconcat 'identity (cons cmd args) " ") "\n"))))
  1242. (calc-graph-view-commands))
  1243. (defun calc-graph-command (cmd)
  1244. (interactive "sGNUPLOT command: ")
  1245. (calc-wrapper
  1246. (calc-graph-init)
  1247. (calc-graph-view-trail)
  1248. (calc-gnuplot-command cmd)
  1249. (or (string= calc-gnuplot-name "pgnuplot")
  1250. (progn
  1251. (accept-process-output)
  1252. (calc-graph-view-trail)))))
  1253. (defun calc-graph-kill (&optional no-view)
  1254. (interactive)
  1255. (calc-graph-delete-temps)
  1256. (if (calc-gnuplot-alive)
  1257. (calc-wrapper
  1258. (or no-view (calc-graph-view-trail))
  1259. (let ((calc-graph-no-wait t))
  1260. (calc-gnuplot-command "exit"))
  1261. (sit-for 1)
  1262. (if (process-status calc-gnuplot-process)
  1263. (delete-process calc-gnuplot-process))
  1264. (setq calc-gnuplot-process nil))))
  1265. (defun calc-graph-quit ()
  1266. (interactive)
  1267. (if (get-buffer-window calc-gnuplot-input)
  1268. (calc-graph-view-commands t))
  1269. (if (get-buffer-window calc-gnuplot-buffer)
  1270. (calc-graph-view-trail t))
  1271. (calc-graph-kill t))
  1272. (defun calc-graph-view-commands (&optional no-need)
  1273. (interactive "p")
  1274. (or calc-graph-no-auto-view (calc-graph-init-buffers))
  1275. (calc-graph-view calc-gnuplot-input calc-gnuplot-buffer (null no-need)))
  1276. (defun calc-graph-view-trail (&optional no-need)
  1277. (interactive "p")
  1278. (or calc-graph-no-auto-view (calc-graph-init-buffers))
  1279. (calc-graph-view calc-gnuplot-buffer calc-gnuplot-input (null no-need)))
  1280. (defun calc-graph-view (buf other-buf need)
  1281. (let (win)
  1282. (or calc-graph-no-auto-view
  1283. (if (setq win (get-buffer-window buf))
  1284. (or need
  1285. (and (eq buf calc-gnuplot-buffer)
  1286. (with-current-buffer buf
  1287. (not (pos-visible-in-window-p (point-max) win))))
  1288. (progn
  1289. (bury-buffer buf)
  1290. (bury-buffer other-buf)
  1291. (let ((curwin (selected-window)))
  1292. (select-window win)
  1293. (switch-to-buffer nil)
  1294. (select-window curwin))))
  1295. (if (setq win (get-buffer-window other-buf))
  1296. (set-window-buffer win buf)
  1297. (if (eq major-mode 'calc-mode)
  1298. (if (or need
  1299. (not (window-full-height-p)))
  1300. (display-buffer buf))
  1301. (switch-to-buffer buf)))))
  1302. (with-current-buffer buf
  1303. (if (and (eq buf calc-gnuplot-buffer)
  1304. (setq win (get-buffer-window buf))
  1305. (not (pos-visible-in-window-p (point-max) win)))
  1306. (progn
  1307. (goto-char (point-max))
  1308. (vertical-motion (- 6 (window-height win)))
  1309. (set-window-start win (point))
  1310. (goto-char (point-max)))))
  1311. (or calc-graph-no-auto-view (sit-for 0))))
  1312. (defun calc-gnuplot-check-for-errors ()
  1313. (if (save-excursion
  1314. (prog2
  1315. (progn
  1316. (set-buffer calc-gnuplot-buffer)
  1317. (goto-char calc-gnuplot-last-error-pos))
  1318. (re-search-forward "^[ \t]+\\^$" nil t)
  1319. (goto-char (point-max))
  1320. (setq calc-gnuplot-last-error-pos (point-max))))
  1321. (calc-graph-view-trail)))
  1322. (defun calc-gnuplot-command (&rest args)
  1323. (calc-graph-init)
  1324. (let ((cmd (concat (mapconcat 'identity args " ") "\n")))
  1325. (or (string= calc-gnuplot-name "pgnuplot")
  1326. (accept-process-output))
  1327. (with-current-buffer calc-gnuplot-buffer
  1328. (calc-gnuplot-check-for-errors)
  1329. (goto-char (point-max))
  1330. (setq calc-gnuplot-trail-mark (point))
  1331. (or (>= calc-gnuplot-version 3)
  1332. (insert cmd))
  1333. (set-marker (process-mark calc-gnuplot-process) (point))
  1334. (process-send-string calc-gnuplot-process cmd)
  1335. (if (get-buffer-window calc-gnuplot-buffer)
  1336. (calc-graph-view-trail))
  1337. (or (string= calc-gnuplot-name "pgnuplot")
  1338. (accept-process-output (and (not calc-graph-no-wait)
  1339. calc-gnuplot-process)))
  1340. (calc-gnuplot-check-for-errors)
  1341. (if (get-buffer-window calc-gnuplot-buffer)
  1342. (calc-graph-view-trail)))))
  1343. (defun calc-graph-init-buffers ()
  1344. (or (and calc-gnuplot-buffer
  1345. (buffer-name calc-gnuplot-buffer))
  1346. (setq calc-gnuplot-buffer (get-buffer-create "*Gnuplot Trail*")))
  1347. (or (and calc-gnuplot-input
  1348. (buffer-name calc-gnuplot-input))
  1349. (setq calc-gnuplot-input (get-buffer-create "*Gnuplot Commands*"))))
  1350. (defun calc-graph-init ()
  1351. (or (calc-gnuplot-alive)
  1352. (let ((process-connection-type t)
  1353. origin)
  1354. (if calc-gnuplot-process
  1355. (progn
  1356. (delete-process calc-gnuplot-process)
  1357. (setq calc-gnuplot-process nil)))
  1358. (calc-graph-init-buffers)
  1359. (with-current-buffer calc-gnuplot-buffer
  1360. (insert "\nStarting gnuplot...\n")
  1361. (setq origin (point)))
  1362. (setq calc-graph-last-device nil)
  1363. (setq calc-graph-last-output nil)
  1364. (if (string= calc-gnuplot-name "pgnuplot")
  1365. (let ((version-str (shell-command-to-string "pgnuplot -V")))
  1366. (if (string-match "gnuplot \\([0-9]+\\)\\." version-str)
  1367. (setq calc-gnuplot-version (string-to-number
  1368. (substring version-str
  1369. (match-beginning 1)
  1370. (match-end 1))))
  1371. (setq calc-gnuplot-version 1))))
  1372. (condition-case err
  1373. (let ((args (append (and calc-gnuplot-display
  1374. (not (equal calc-gnuplot-display
  1375. (getenv "DISPLAY")))
  1376. (not (string= calc-gnuplot-name "pgnuplot"))
  1377. (list "-display"
  1378. calc-gnuplot-display))
  1379. (and calc-gnuplot-geometry
  1380. (not (string= calc-gnuplot-name "pgnuplot"))
  1381. (list "-geometry"
  1382. calc-gnuplot-geometry)))))
  1383. (setq calc-gnuplot-process
  1384. (apply 'start-process
  1385. "gnuplot"
  1386. calc-gnuplot-buffer
  1387. calc-gnuplot-name
  1388. args))
  1389. (set-process-query-on-exit-flag calc-gnuplot-process nil))
  1390. (file-error
  1391. (error "Sorry, can't find \"%s\" on your system"
  1392. calc-gnuplot-name)))
  1393. (with-current-buffer calc-gnuplot-buffer
  1394. (while (and (not (string= calc-gnuplot-name "pgnuplot"))
  1395. (not (save-excursion
  1396. (goto-char origin)
  1397. (search-forward "gnuplot> " nil t)))
  1398. (memq (process-status calc-gnuplot-process) '(run stop)))
  1399. (accept-process-output calc-gnuplot-process))
  1400. (or (memq (process-status calc-gnuplot-process) '(run stop))
  1401. (error "Unable to start GNUPLOT process"))
  1402. (if (not (string= calc-gnuplot-name "pgnuplot"))
  1403. (if (save-excursion
  1404. (goto-char origin)
  1405. (re-search-forward
  1406. "G N U P L O T.*\n.*version \\([0-9]+\\)\\." nil t))
  1407. (setq calc-gnuplot-version
  1408. (string-to-number (buffer-substring
  1409. (match-beginning 1)
  1410. (match-end 1))))
  1411. (setq calc-gnuplot-version 1)))
  1412. (goto-char (point-max)))))
  1413. (with-current-buffer calc-gnuplot-input
  1414. (if (= (buffer-size) 0)
  1415. (insert "# Commands for running gnuplot\n\n\n")
  1416. (or calc-graph-no-auto-view
  1417. (eq (char-after (1- (point-max))) ?\n)
  1418. (progn
  1419. (goto-char (point-max))
  1420. (insert "\n"))))))
  1421. (provide 'calc-graph)
  1422. ;;; calc-graph.el ends here