calc-graph.el 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509
  1. ;;; calc-graph.el --- graph output functions for Calc
  2. ;; Copyright (C) 1990-1993, 2001-2012 Free Software Foundation, Inc.
  3. ;; Author: David Gillespie <daveg@synaptics.com>
  4. ;; Maintainer: Jay Belanger <jay.p.belanger@gmail.com>
  5. ;; This file is part of GNU Emacs.
  6. ;; GNU Emacs is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; GNU Emacs is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;;; Code:
  18. ;; This file is autoloaded from calc-ext.el.
  19. (require 'calc-ext)
  20. (require 'calc-macs)
  21. ;;; Graphics
  22. ;; The following three variables are customizable and defined in calc.el.
  23. (defvar calc-gnuplot-name)
  24. (defvar calc-gnuplot-plot-command)
  25. (defvar calc-gnuplot-print-command)
  26. (defvar calc-gnuplot-tempfile "calc")
  27. (defvar calc-gnuplot-default-device)
  28. (defvar calc-gnuplot-default-output)
  29. (defvar calc-gnuplot-print-device)
  30. (defvar calc-gnuplot-print-output)
  31. (defvar calc-gnuplot-keep-outfile nil)
  32. (defvar calc-gnuplot-version nil)
  33. (defvar calc-gnuplot-display (getenv "DISPLAY"))
  34. (defvar calc-gnuplot-geometry)
  35. (defvar calc-graph-default-resolution)
  36. (defvar calc-graph-default-resolution-3d)
  37. (defvar calc-graph-default-precision 5)
  38. (defvar calc-gnuplot-buffer nil)
  39. (defvar calc-gnuplot-input nil)
  40. (defvar calc-gnuplot-last-error-pos 1)
  41. (defvar calc-graph-last-device nil)
  42. (defvar calc-graph-last-output nil)
  43. (defvar calc-graph-file-cache nil)
  44. (defvar calc-graph-var-cache nil)
  45. (defvar calc-graph-data-cache nil)
  46. (defvar calc-graph-data-cache-limit 10)
  47. (defvar calc-graph-no-auto-view nil)
  48. (defvar calc-graph-no-wait nil)
  49. (defvar calc-gnuplot-trail-mark)
  50. (defun calc-graph-fast (many)
  51. (interactive "P")
  52. (let ((calc-graph-no-auto-view t))
  53. (calc-graph-delete t)
  54. (calc-graph-add many)
  55. (calc-graph-plot nil)))
  56. (defun calc-graph-fast-3d (many)
  57. (interactive "P")
  58. (let ((calc-graph-no-auto-view t))
  59. (calc-graph-delete t)
  60. (calc-graph-add-3d many)
  61. (calc-graph-plot nil)))
  62. (defun calc-graph-delete (all)
  63. (interactive "P")
  64. (calc-wrapper
  65. (calc-graph-init)
  66. (with-current-buffer calc-gnuplot-input
  67. (and (calc-graph-find-plot t all)
  68. (progn
  69. (if (looking-at "s?plot")
  70. (progn
  71. (setq calc-graph-var-cache nil)
  72. (delete-region (point) (point-max)))
  73. (delete-region (point) (1- (point-max)))))))
  74. (calc-graph-view-commands)))
  75. (defun calc-graph-find-plot (&optional before all)
  76. (goto-char (point-min))
  77. (and (re-search-forward "^s?plot[ \t]+" nil t)
  78. (let ((beg (point)))
  79. (goto-char (point-max))
  80. (if (or all
  81. (not (search-backward "," nil t))
  82. (< (point) beg))
  83. (progn
  84. (goto-char beg)
  85. (if before
  86. (beginning-of-line)))
  87. (or before
  88. (re-search-forward ",[ \t]+")))
  89. t)))
  90. (defun calc-graph-add (many)
  91. (interactive "P")
  92. (calc-wrapper
  93. (calc-graph-init)
  94. (cond ((null many)
  95. (calc-graph-add-curve (calc-graph-lookup (calc-top-n 2))
  96. (calc-graph-lookup (calc-top-n 1))))
  97. ((or (consp many) (eq many 0))
  98. (let ((xdata (calc-graph-lookup (calc-top-n 2)))
  99. (ylist (calc-top-n 1)))
  100. (or (eq (car-safe ylist) 'vec)
  101. (error "Y argument must be a vector"))
  102. (while (setq ylist (cdr ylist))
  103. (calc-graph-add-curve xdata (calc-graph-lookup (car ylist))))))
  104. ((> (setq many (prefix-numeric-value many)) 0)
  105. (let ((xdata (calc-graph-lookup (calc-top-n (1+ many)))))
  106. (while (> many 0)
  107. (calc-graph-add-curve xdata
  108. (calc-graph-lookup (calc-top-n many)))
  109. (setq many (1- many)))))
  110. (t
  111. (let (pair)
  112. (setq many (- many))
  113. (while (> many 0)
  114. (setq pair (calc-top-n many))
  115. (or (and (eq (car-safe pair) 'vec)
  116. (= (length pair) 3))
  117. (error "Argument must be an [x,y] vector"))
  118. (calc-graph-add-curve (calc-graph-lookup (nth 1 pair))
  119. (calc-graph-lookup (nth 2 pair)))
  120. (setq many (1- many))))))
  121. (calc-graph-view-commands)))
  122. (defun calc-graph-add-3d (many)
  123. (interactive "P")
  124. (calc-wrapper
  125. (calc-graph-init)
  126. (cond ((null many)
  127. (calc-graph-add-curve (calc-graph-lookup (calc-top-n 3))
  128. (calc-graph-lookup (calc-top-n 2))
  129. (calc-graph-lookup (calc-top-n 1))))
  130. ((or (consp many) (eq many 0))
  131. (let ((xdata (calc-graph-lookup (calc-top-n 3)))
  132. (ydata (calc-graph-lookup (calc-top-n 2)))
  133. (zlist (calc-top-n 1)))
  134. (or (eq (car-safe zlist) 'vec)
  135. (error "Z argument must be a vector"))
  136. (while (setq zlist (cdr zlist))
  137. (calc-graph-add-curve xdata ydata
  138. (calc-graph-lookup (car zlist))))))
  139. ((> (setq many (prefix-numeric-value many)) 0)
  140. (let ((xdata (calc-graph-lookup (calc-top-n (+ many 2))))
  141. (ydata (calc-graph-lookup (calc-top-n (+ many 1)))))
  142. (while (> many 0)
  143. (calc-graph-add-curve xdata ydata
  144. (calc-graph-lookup (calc-top-n many)))
  145. (setq many (1- many)))))
  146. (t
  147. (let (curve)
  148. (setq many (- many))
  149. (while (> many 0)
  150. (setq curve (calc-top-n many))
  151. (or (and (eq (car-safe curve) 'vec)
  152. (= (length curve) 4))
  153. (error "Argument must be an [x,y,z] vector"))
  154. (calc-graph-add-curve (calc-graph-lookup (nth 1 curve))
  155. (calc-graph-lookup (nth 2 curve))
  156. (calc-graph-lookup (nth 3 curve)))
  157. (setq many (1- many))))))
  158. (calc-graph-view-commands)))
  159. (defun calc-graph-add-curve (xdata ydata &optional zdata)
  160. (let ((num (calc-graph-count-curves))
  161. (pstyle (calc-var-value 'var-PointStyles))
  162. (lstyle (calc-var-value 'var-LineStyles)))
  163. (with-current-buffer calc-gnuplot-input
  164. (goto-char (point-min))
  165. (if (re-search-forward (if zdata "^plot[ \t]" "^splot[ \t]")
  166. nil t)
  167. (error "Can't mix 2d and 3d curves on one graph"))
  168. (if (re-search-forward "^s?plot[ \t]" nil t)
  169. (progn
  170. (end-of-line)
  171. (insert ", "))
  172. (goto-char (point-max))
  173. (or (eq (preceding-char) ?\n)
  174. (insert "\n"))
  175. (insert (if zdata "splot" "plot") " \n")
  176. (forward-char -1))
  177. (insert "{" (symbol-name (nth 1 xdata))
  178. ":" (symbol-name (nth 1 ydata)))
  179. (if zdata
  180. (insert ":" (symbol-name (nth 1 zdata))))
  181. (insert "} "
  182. "title \"" (symbol-name (nth 1 ydata)) "\" "
  183. "with dots")
  184. (setq pstyle (and (eq (car-safe pstyle) 'vec) (nth (1+ num) pstyle)))
  185. (setq lstyle (and (eq (car-safe lstyle) 'vec) (nth (1+ num) lstyle))))
  186. (calc-graph-set-styles
  187. (or (and (Math-num-integerp lstyle) (math-trunc lstyle))
  188. 0)
  189. (or (and (Math-num-integerp pstyle) (math-trunc pstyle))
  190. (if (eq (car-safe (calc-var-value (nth 2 ydata))) 'vec)
  191. 0 -1))
  192. (math-contains-sdev-p (eval (nth 2 ydata))))))
  193. (defun calc-graph-lookup (thing)
  194. (if (and (eq (car-safe thing) 'var)
  195. (calc-var-value (nth 2 thing)))
  196. thing
  197. (let ((found (assoc thing calc-graph-var-cache)))
  198. (or found
  199. (let ((varname (concat "PlotData"
  200. (int-to-string
  201. (1+ (length calc-graph-var-cache)))))
  202. var)
  203. (setq var (list 'var (intern varname)
  204. (intern (concat "var-" varname)))
  205. found (cons thing var)
  206. calc-graph-var-cache (cons found calc-graph-var-cache))
  207. (set (nth 2 var) thing)))
  208. (cdr found))))
  209. (defun calc-graph-juggle (arg)
  210. (interactive "p")
  211. (calc-graph-init)
  212. (with-current-buffer calc-gnuplot-input
  213. (if (< arg 0)
  214. (let ((num (calc-graph-count-curves)))
  215. (if (> num 0)
  216. (while (< arg 0)
  217. (setq arg (+ arg num))))))
  218. (while (>= (setq arg (1- arg)) 0)
  219. (calc-graph-do-juggle))))
  220. (defun calc-graph-count-curves ()
  221. (with-current-buffer calc-gnuplot-input
  222. (if (re-search-forward "^s?plot[ \t]" nil t)
  223. (let ((num 1))
  224. (goto-char (point-min))
  225. (while (search-forward "," nil t)
  226. (setq num (1+ num)))
  227. num)
  228. 0)))
  229. (defun calc-graph-do-juggle ()
  230. (let (base)
  231. (and (calc-graph-find-plot t t)
  232. (progn
  233. (setq base (point))
  234. (calc-graph-find-plot t nil)
  235. (or (eq base (point))
  236. (let ((str (buffer-substring (+ (point) 2) (1- (point-max)))))
  237. (delete-region (point) (1- (point-max)))
  238. (goto-char (+ base 5))
  239. (insert str ", ")))))))
  240. (defun calc-graph-print (flag)
  241. (interactive "P")
  242. (calc-graph-plot flag t))
  243. (defvar var-DUMMY)
  244. (defvar var-DUMMY2)
  245. (defvar var-PlotRejects)
  246. ;; The following variables are local to calc-graph-plot, but are
  247. ;; used in the functions calc-graph-compute-2d, calc-graph-refine-2d,
  248. ;; calc-graph-recompute-2d, calc-graph-compute-3d and
  249. ;; calc-graph-format-data, which are called by calc-graph-plot.
  250. (defvar calc-graph-yvalue)
  251. (defvar calc-graph-yvec)
  252. (defvar calc-graph-numsteps)
  253. (defvar calc-graph-numsteps3)
  254. (defvar calc-graph-xvalue)
  255. (defvar calc-graph-xvec)
  256. (defvar calc-graph-xname)
  257. (defvar calc-graph-yname)
  258. (defvar calc-graph-xstep)
  259. (defvar calc-graph-ycache)
  260. (defvar calc-graph-ycacheptr)
  261. (defvar calc-graph-refine)
  262. (defvar calc-graph-keep-file)
  263. (defvar calc-graph-xval)
  264. (defvar calc-graph-xlow)
  265. (defvar calc-graph-xhigh)
  266. (defvar calc-graph-yval)
  267. (defvar calc-graph-yp)
  268. (defvar calc-graph-xp)
  269. (defvar calc-graph-zp)
  270. (defvar calc-graph-yvector)
  271. (defvar calc-graph-resolution)
  272. (defvar calc-graph-y3value)
  273. (defvar calc-graph-y3name)
  274. (defvar calc-graph-y3step)
  275. (defvar calc-graph-zval)
  276. (defvar calc-graph-stepcount)
  277. (defvar calc-graph-is-splot)
  278. (defvar calc-graph-surprise-splot)
  279. (defvar calc-graph-blank)
  280. (defvar calc-graph-non-blank)
  281. (defvar calc-graph-curve-num)
  282. (defun calc-graph-plot (flag &optional printing)
  283. (interactive "P")
  284. (calc-slow-wrapper
  285. (let ((calcbuf (current-buffer))
  286. (tempbuf (get-buffer-create "*Gnuplot Temp-2*"))
  287. (tempbuftop 1)
  288. (tempoutfile nil)
  289. (calc-graph-curve-num 0)
  290. (calc-graph-refine (and flag (> (prefix-numeric-value flag) 0)))
  291. (recompute (and flag (< (prefix-numeric-value flag) 0)))
  292. (calc-graph-surprise-splot nil)
  293. (tty-output nil)
  294. cache-env calc-graph-is-splot device output calc-graph-resolution precision samples-pos)
  295. (add-hook 'kill-emacs-hook 'calc-graph-kill-hook)
  296. (save-excursion
  297. (calc-graph-init)
  298. (set-buffer tempbuf)
  299. (erase-buffer)
  300. (set-buffer calc-gnuplot-input)
  301. (goto-char (point-min))
  302. (setq calc-graph-is-splot (re-search-forward "^splot[ \t]" nil t))
  303. (let ((str (buffer-string))
  304. (ver calc-gnuplot-version))
  305. (set-buffer (get-buffer-create "*Gnuplot Temp*"))
  306. (erase-buffer)
  307. (insert "# (Note: This is a temporary copy---do not edit!)\n")
  308. (if (>= ver 2)
  309. (insert "set noarrow\nset nolabel\n"
  310. "set autoscale xy\nset nologscale xy\n"
  311. "set xlabel\nset ylabel\nset title\n"
  312. "set noclip points\nset clip one\nset clip two\n"
  313. "set format \"%g\"\nset tics\nset xtics\nset ytics\n"
  314. "set style data linespoints\n"
  315. "set nogrid\nset nokey\nset nopolar\n"))
  316. (if (>= ver 3)
  317. (insert "set surface\nset nocontour\n"
  318. "set " (if calc-graph-is-splot "" "no") "parametric\n"
  319. "set notime\nset border\nset ztics\nset zeroaxis\n"
  320. "set view 60,30,1,1\nset offsets 0,0,0,0\n"))
  321. (setq samples-pos (point))
  322. (insert "\n\n" str))
  323. (goto-char (point-min))
  324. (if calc-graph-is-splot
  325. (if calc-graph-refine
  326. (error "This option works only for 2d plots")
  327. (setq recompute t)))
  328. (let ((calc-gnuplot-input (current-buffer))
  329. (calc-graph-no-auto-view t))
  330. (if printing
  331. (setq device calc-gnuplot-print-device
  332. output calc-gnuplot-print-output)
  333. (setq device (calc-graph-find-command "terminal")
  334. output (calc-graph-find-command "output"))
  335. (or device
  336. (setq device calc-gnuplot-default-device))
  337. (if output
  338. (setq output (car (read-from-string output)))
  339. (setq output calc-gnuplot-default-output)))
  340. (if (or (equal device "") (equal device "default"))
  341. (setq device
  342. (cond
  343. (printing "postscript")
  344. ;; Check MS-Windows before X, in case they have
  345. ;; $DISPLAY set for some reason (e.g., Cygwin or
  346. ;; whatever)
  347. ((string= calc-gnuplot-name "pgnuplot")
  348. "windows")
  349. ((or (eq window-system 'x) (getenv "DISPLAY"))
  350. "x11")
  351. ((>= calc-gnuplot-version 3)
  352. "dumb")
  353. (t "postscript"))))
  354. (if (equal device "dumb")
  355. (setq device (format "dumb %d %d"
  356. (1- (frame-width)) (1- (frame-height)))))
  357. (if (equal device "big")
  358. (setq device (format "dumb %d %d"
  359. (* 4 (- (frame-width) 3))
  360. (* 4 (- (frame-height) 3)))))
  361. (if (stringp output)
  362. (if (or (equal output "auto")
  363. (and (equal output "tty") (setq tty-output t)))
  364. (setq tempoutfile (calc-temp-file-name -1)
  365. output tempoutfile))
  366. (setq output (eval output)))
  367. (or (equal device calc-graph-last-device)
  368. (progn
  369. (setq calc-graph-last-device device)
  370. (calc-gnuplot-command "set terminal" device)))
  371. (or (equal output calc-graph-last-output)
  372. (progn
  373. (setq calc-graph-last-output output)
  374. (calc-gnuplot-command "set output"
  375. (if (equal output "STDOUT")
  376. ""
  377. (prin1-to-string output)))))
  378. (setq calc-graph-resolution (calc-graph-find-command "samples"))
  379. (if calc-graph-resolution
  380. (setq calc-graph-resolution (string-to-number calc-graph-resolution))
  381. (setq calc-graph-resolution (if calc-graph-is-splot
  382. calc-graph-default-resolution-3d
  383. calc-graph-default-resolution)))
  384. (setq precision (calc-graph-find-command "precision"))
  385. (if precision
  386. (setq precision (string-to-number precision))
  387. (setq precision calc-graph-default-precision))
  388. (calc-graph-set-command "terminal")
  389. (calc-graph-set-command "output")
  390. (calc-graph-set-command "samples")
  391. (calc-graph-set-command "precision"))
  392. (goto-char samples-pos)
  393. (insert "set samples " (int-to-string (max (if calc-graph-is-splot 20 200)
  394. (+ 5 calc-graph-resolution))) "\n")
  395. (while (re-search-forward "{\\*[^}]+}[^,\n]*" nil t)
  396. (delete-region (match-beginning 0) (match-end 0))
  397. (if (looking-at ",")
  398. (delete-char 1)
  399. (while (memq (preceding-char) '(?\s ?\t))
  400. (forward-char -1))
  401. (if (eq (preceding-char) ?\,)
  402. (delete-char -1))))
  403. (with-current-buffer calcbuf
  404. (setq cache-env (list calc-angle-mode
  405. calc-complex-mode
  406. calc-simplify-mode
  407. calc-infinite-mode
  408. calc-word-size
  409. precision calc-graph-is-splot))
  410. (if (and (not recompute)
  411. (equal (cdr (car calc-graph-data-cache)) cache-env))
  412. (while (> (length calc-graph-data-cache)
  413. calc-graph-data-cache-limit)
  414. (setcdr calc-graph-data-cache
  415. (cdr (cdr calc-graph-data-cache))))
  416. (setq calc-graph-data-cache (list (cons nil cache-env)))))
  417. (calc-graph-find-plot t t)
  418. (while (re-search-forward
  419. (if calc-graph-is-splot
  420. "{\\([^{}:\n]+\\):\\([^{}:\n]+\\):\\([^{}:\n]+\\)}"
  421. "{\\([^{}:\n]+\\)\\(:\\)\\([^{}:\n]+\\)}")
  422. nil t)
  423. (setq calc-graph-curve-num (1+ calc-graph-curve-num))
  424. (let* ((calc-graph-xname (buffer-substring (match-beginning 1) (match-end 1)))
  425. (xvar (intern (concat "var-" calc-graph-xname)))
  426. (calc-graph-xvalue (math-evaluate-expr (calc-var-value xvar)))
  427. (calc-graph-y3name (and calc-graph-is-splot
  428. (buffer-substring (match-beginning 2)
  429. (match-end 2))))
  430. (y3var (and calc-graph-is-splot (intern (concat "var-" calc-graph-y3name))))
  431. (calc-graph-y3value (and calc-graph-is-splot (calc-var-value y3var)))
  432. (calc-graph-yname (buffer-substring (match-beginning 3) (match-end 3)))
  433. (yvar (intern (concat "var-" calc-graph-yname)))
  434. (calc-graph-yvalue (calc-var-value yvar))
  435. filename)
  436. (delete-region (match-beginning 0) (match-end 0))
  437. (setq filename (calc-temp-file-name calc-graph-curve-num))
  438. (with-current-buffer calcbuf
  439. (let (tempbuftop
  440. (calc-graph-xp calc-graph-xvalue)
  441. (calc-graph-yp calc-graph-yvalue)
  442. (calc-graph-zp nil)
  443. (calc-graph-xlow nil) (calc-graph-xhigh nil) (y3low nil) (y3high nil)
  444. calc-graph-xvec calc-graph-xval calc-graph-xstep var-DUMMY
  445. y3val calc-graph-y3step var-DUMMY2 (calc-graph-zval nil)
  446. calc-graph-yvec calc-graph-yval calc-graph-ycache calc-graph-ycacheptr calc-graph-yvector
  447. calc-graph-numsteps calc-graph-numsteps3
  448. (calc-graph-keep-file (and (not calc-graph-is-splot) (file-exists-p filename)))
  449. (calc-graph-stepcount 0)
  450. (calc-symbolic-mode nil)
  451. (calc-prefer-frac nil)
  452. (calc-internal-prec (max 3 precision))
  453. (calc-simplify-mode (and (not (memq calc-simplify-mode
  454. '(none num)))
  455. calc-simplify-mode))
  456. (calc-graph-blank t)
  457. (calc-graph-non-blank nil)
  458. (math-working-step 0)
  459. (math-working-step-2 nil))
  460. (save-excursion
  461. (if calc-graph-is-splot
  462. (calc-graph-compute-3d)
  463. (calc-graph-compute-2d))
  464. (set-buffer tempbuf)
  465. (goto-char (point-max))
  466. (insert "\n" calc-graph-xname)
  467. (if calc-graph-is-splot
  468. (insert ":" calc-graph-y3name))
  469. (insert ":" calc-graph-yname "\n\n")
  470. (setq tempbuftop (point))
  471. (let ((calc-group-digits nil)
  472. (calc-leading-zeros nil)
  473. (calc-number-radix 10)
  474. (calc-twos-complement-mode nil)
  475. (entry (and (not calc-graph-is-splot)
  476. (list calc-graph-xp calc-graph-yp calc-graph-xhigh calc-graph-numsteps))))
  477. (or (equal entry
  478. (nth 1 (nth (1+ calc-graph-curve-num)
  479. calc-graph-file-cache)))
  480. (setq calc-graph-keep-file nil))
  481. (setcar (cdr (nth (1+ calc-graph-curve-num) calc-graph-file-cache))
  482. entry)
  483. (or calc-graph-keep-file
  484. (calc-graph-format-data)))
  485. (or calc-graph-keep-file
  486. (progn
  487. (or calc-graph-non-blank
  488. (error "No valid data points for %s:%s"
  489. calc-graph-xname calc-graph-yname))
  490. (write-region tempbuftop (point-max) filename
  491. nil 'quiet))))))
  492. (insert (prin1-to-string filename))))
  493. (if calc-graph-surprise-splot
  494. (setcdr cache-env nil))
  495. (if (= calc-graph-curve-num 0)
  496. (progn
  497. (calc-gnuplot-command "clear")
  498. (calc-clear-command-flag 'clear-message)
  499. (message "No data to plot!"))
  500. (setq calc-graph-data-cache-limit (max calc-graph-curve-num
  501. calc-graph-data-cache-limit))
  502. (let ((filename (calc-temp-file-name 0)))
  503. (write-region (point-min) (point-max) filename nil 'quiet)
  504. (calc-gnuplot-command "load" (prin1-to-string filename)))
  505. (or (equal output "STDOUT")
  506. calc-gnuplot-keep-outfile
  507. (progn ; need to close the output file before printing/plotting
  508. (setq calc-graph-last-output "STDOUT")
  509. (calc-gnuplot-command "set output")))
  510. (let ((command (if printing
  511. calc-gnuplot-print-command
  512. (or calc-gnuplot-plot-command
  513. (and (string-match "^dumb" device)
  514. 'calc-graph-show-dumb)
  515. (and tty-output
  516. 'calc-graph-show-tty)))))
  517. (if command
  518. (if (stringp command)
  519. (calc-gnuplot-command
  520. "!" (format command
  521. (or tempoutfile
  522. calc-gnuplot-print-output)))
  523. (if (symbolp command)
  524. (funcall command output)
  525. (eval command))))))))))
  526. (defun calc-graph-compute-2d ()
  527. (if (setq calc-graph-yvec (eq (car-safe calc-graph-yvalue) 'vec))
  528. (if (= (setq calc-graph-numsteps (1- (length calc-graph-yvalue))) 0)
  529. (error "Can't plot an empty vector")
  530. (if (setq calc-graph-xvec (eq (car-safe calc-graph-xvalue) 'vec))
  531. (or (= (1- (length calc-graph-xvalue)) calc-graph-numsteps)
  532. (error "%s and %s have different lengths" calc-graph-xname calc-graph-yname))
  533. (if (and (eq (car-safe calc-graph-xvalue) 'intv)
  534. (math-constp calc-graph-xvalue))
  535. (setq calc-graph-xstep (math-div (math-sub (nth 3 calc-graph-xvalue)
  536. (nth 2 calc-graph-xvalue))
  537. (1- calc-graph-numsteps))
  538. calc-graph-xvalue (nth 2 calc-graph-xvalue))
  539. (if (math-realp calc-graph-xvalue)
  540. (setq calc-graph-xstep 1)
  541. (error "%s is not a suitable basis for %s" calc-graph-xname calc-graph-yname)))))
  542. (or (math-realp calc-graph-yvalue)
  543. (let ((math-arglist nil))
  544. (setq calc-graph-yvalue (math-evaluate-expr calc-graph-yvalue))
  545. (calc-default-formula-arglist calc-graph-yvalue)
  546. (or math-arglist
  547. (error "%s does not contain any unassigned variables" calc-graph-yname))
  548. (and (cdr math-arglist)
  549. (error "%s contains more than one variable: %s"
  550. calc-graph-yname math-arglist))
  551. (setq calc-graph-yvalue (math-expr-subst calc-graph-yvalue
  552. (math-build-var-name (car math-arglist))
  553. '(var DUMMY var-DUMMY)))))
  554. (setq calc-graph-ycache (assoc calc-graph-yvalue calc-graph-data-cache))
  555. (delq calc-graph-ycache calc-graph-data-cache)
  556. (nconc calc-graph-data-cache
  557. (list (or calc-graph-ycache (setq calc-graph-ycache (list calc-graph-yvalue)))))
  558. (if (and (not (setq calc-graph-xvec (eq (car-safe calc-graph-xvalue) 'vec)))
  559. calc-graph-refine (cdr (cdr calc-graph-ycache)))
  560. (calc-graph-refine-2d)
  561. (calc-graph-recompute-2d))))
  562. (defun calc-graph-refine-2d ()
  563. (setq calc-graph-keep-file nil
  564. calc-graph-ycacheptr (cdr calc-graph-ycache))
  565. (if (and (setq calc-graph-xval (calc-graph-find-command "xrange"))
  566. (string-match "\\`\\[\\([0-9.eE+-]*\\):\\([0-9.eE+-]*\\)\\]\\'"
  567. calc-graph-xval))
  568. (let ((b2 (match-beginning 2))
  569. (e2 (match-end 2)))
  570. (setq calc-graph-xlow (math-read-number (substring calc-graph-xval
  571. (match-beginning 1)
  572. (match-end 1)))
  573. calc-graph-xhigh (math-read-number (substring calc-graph-xval b2 e2))))
  574. (if calc-graph-xlow
  575. (while (and (cdr calc-graph-ycacheptr)
  576. (Math-lessp (car (nth 1 calc-graph-ycacheptr)) calc-graph-xlow))
  577. (setq calc-graph-ycacheptr (cdr calc-graph-ycacheptr)))))
  578. (setq math-working-step-2 (1- (length calc-graph-ycacheptr)))
  579. (while (and (cdr calc-graph-ycacheptr)
  580. (or (not calc-graph-xhigh)
  581. (Math-lessp (car (car calc-graph-ycacheptr)) calc-graph-xhigh)))
  582. (setq var-DUMMY (math-div (math-add (car (car calc-graph-ycacheptr))
  583. (car (nth 1 calc-graph-ycacheptr)))
  584. 2)
  585. math-working-step (1+ math-working-step)
  586. calc-graph-yval (math-evaluate-expr calc-graph-yvalue))
  587. (setcdr calc-graph-ycacheptr (cons (cons var-DUMMY calc-graph-yval)
  588. (cdr calc-graph-ycacheptr)))
  589. (setq calc-graph-ycacheptr (cdr (cdr calc-graph-ycacheptr))))
  590. (setq calc-graph-yp calc-graph-ycache
  591. calc-graph-numsteps 1000000))
  592. (defun calc-graph-recompute-2d ()
  593. (setq calc-graph-ycacheptr calc-graph-ycache)
  594. (if calc-graph-xvec
  595. (setq calc-graph-numsteps (1- (length calc-graph-xvalue))
  596. calc-graph-yvector nil)
  597. (if (and (eq (car-safe calc-graph-xvalue) 'intv)
  598. (math-constp calc-graph-xvalue))
  599. (setq calc-graph-numsteps calc-graph-resolution
  600. calc-graph-yp nil
  601. calc-graph-xlow (nth 2 calc-graph-xvalue)
  602. calc-graph-xhigh (nth 3 calc-graph-xvalue)
  603. calc-graph-xstep (math-div (math-sub calc-graph-xhigh calc-graph-xlow)
  604. (1- calc-graph-numsteps))
  605. calc-graph-xvalue (nth 2 calc-graph-xvalue))
  606. (error "%s is not a suitable basis for %s"
  607. calc-graph-xname calc-graph-yname)))
  608. (setq math-working-step-2 calc-graph-numsteps)
  609. (while (>= (setq calc-graph-numsteps (1- calc-graph-numsteps)) 0)
  610. (setq math-working-step (1+ math-working-step))
  611. (if calc-graph-xvec
  612. (progn
  613. (setq calc-graph-xp (cdr calc-graph-xp)
  614. calc-graph-xval (car calc-graph-xp))
  615. (and (not (eq calc-graph-ycacheptr calc-graph-ycache))
  616. (consp (car calc-graph-ycacheptr))
  617. (not (Math-lessp (car (car calc-graph-ycacheptr)) calc-graph-xval))
  618. (setq calc-graph-ycacheptr calc-graph-ycache)))
  619. (if (= calc-graph-numsteps 0)
  620. (setq calc-graph-xval calc-graph-xhigh) ; avoid cumulative roundoff
  621. (setq calc-graph-xval calc-graph-xvalue
  622. calc-graph-xvalue (math-add calc-graph-xvalue calc-graph-xstep))))
  623. (while (and (cdr calc-graph-ycacheptr)
  624. (Math-lessp (car (nth 1 calc-graph-ycacheptr)) calc-graph-xval))
  625. (setq calc-graph-ycacheptr (cdr calc-graph-ycacheptr)))
  626. (or (and (cdr calc-graph-ycacheptr)
  627. (Math-equal (car (nth 1 calc-graph-ycacheptr)) calc-graph-xval))
  628. (progn
  629. (setq calc-graph-keep-file nil
  630. var-DUMMY calc-graph-xval)
  631. (setcdr calc-graph-ycacheptr (cons (cons calc-graph-xval (math-evaluate-expr calc-graph-yvalue))
  632. (cdr calc-graph-ycacheptr)))))
  633. (setq calc-graph-ycacheptr (cdr calc-graph-ycacheptr))
  634. (if calc-graph-xvec
  635. (setq calc-graph-yvector (cons (cdr (car calc-graph-ycacheptr)) calc-graph-yvector))
  636. (or calc-graph-yp (setq calc-graph-yp calc-graph-ycacheptr))))
  637. (if calc-graph-xvec
  638. (setq calc-graph-xp calc-graph-xvalue
  639. calc-graph-yvec t
  640. calc-graph-yp (cons 'vec (nreverse calc-graph-yvector))
  641. calc-graph-numsteps (1- (length calc-graph-xp)))
  642. (setq calc-graph-numsteps 1000000)))
  643. (defun calc-graph-compute-3d ()
  644. (if (setq calc-graph-yvec (eq (car-safe calc-graph-yvalue) 'vec))
  645. (if (math-matrixp calc-graph-yvalue)
  646. (progn
  647. (setq calc-graph-numsteps (1- (length calc-graph-yvalue))
  648. calc-graph-numsteps3 (1- (length (nth 1 calc-graph-yvalue))))
  649. (if (eq (car-safe calc-graph-xvalue) 'vec)
  650. (or (= (1- (length calc-graph-xvalue)) calc-graph-numsteps)
  651. (error "%s has wrong length" calc-graph-xname))
  652. (if (and (eq (car-safe calc-graph-xvalue) 'intv)
  653. (math-constp calc-graph-xvalue))
  654. (setq calc-graph-xvalue (calcFunc-index calc-graph-numsteps
  655. (nth 2 calc-graph-xvalue)
  656. (math-div
  657. (math-sub (nth 3 calc-graph-xvalue)
  658. (nth 2 calc-graph-xvalue))
  659. (1- calc-graph-numsteps))))
  660. (if (math-realp calc-graph-xvalue)
  661. (setq calc-graph-xvalue (calcFunc-index calc-graph-numsteps calc-graph-xvalue 1))
  662. (error "%s is not a suitable basis for %s" calc-graph-xname calc-graph-yname))))
  663. (if (eq (car-safe calc-graph-y3value) 'vec)
  664. (or (= (1- (length calc-graph-y3value)) calc-graph-numsteps3)
  665. (error "%s has wrong length" calc-graph-y3name))
  666. (if (and (eq (car-safe calc-graph-y3value) 'intv)
  667. (math-constp calc-graph-y3value))
  668. (setq calc-graph-y3value (calcFunc-index calc-graph-numsteps3
  669. (nth 2 calc-graph-y3value)
  670. (math-div
  671. (math-sub (nth 3 calc-graph-y3value)
  672. (nth 2 calc-graph-y3value))
  673. (1- calc-graph-numsteps3))))
  674. (if (math-realp calc-graph-y3value)
  675. (setq calc-graph-y3value (calcFunc-index calc-graph-numsteps3 calc-graph-y3value 1))
  676. (error "%s is not a suitable basis for %s" calc-graph-y3name calc-graph-yname))))
  677. (setq calc-graph-xp nil
  678. calc-graph-yp nil
  679. calc-graph-zp nil
  680. calc-graph-xvec t)
  681. (while (setq calc-graph-xvalue (cdr calc-graph-xvalue) calc-graph-yvalue (cdr calc-graph-yvalue))
  682. (setq calc-graph-xp (nconc calc-graph-xp (make-list (1+ calc-graph-numsteps3) (car calc-graph-xvalue)))
  683. calc-graph-yp (nconc calc-graph-yp (cons 0 (copy-sequence (cdr calc-graph-y3value))))
  684. calc-graph-zp (nconc calc-graph-zp (cons '(skip)
  685. (copy-sequence (cdr (car calc-graph-yvalue)))))))
  686. (setq calc-graph-numsteps (1- (* calc-graph-numsteps
  687. (1+ calc-graph-numsteps3)))))
  688. (if (= (setq calc-graph-numsteps (1- (length calc-graph-yvalue))) 0)
  689. (error "Can't plot an empty vector"))
  690. (or (and (eq (car-safe calc-graph-xvalue) 'vec)
  691. (= (1- (length calc-graph-xvalue)) calc-graph-numsteps))
  692. (error "%s is not a suitable basis for %s" calc-graph-xname calc-graph-yname))
  693. (or (and (eq (car-safe calc-graph-y3value) 'vec)
  694. (= (1- (length calc-graph-y3value)) calc-graph-numsteps))
  695. (error "%s is not a suitable basis for %s" calc-graph-y3name calc-graph-yname))
  696. (setq calc-graph-xp calc-graph-xvalue
  697. calc-graph-yp calc-graph-y3value
  698. calc-graph-zp calc-graph-yvalue
  699. calc-graph-xvec t))
  700. (or (math-realp calc-graph-yvalue)
  701. (let ((math-arglist nil))
  702. (setq calc-graph-yvalue (math-evaluate-expr calc-graph-yvalue))
  703. (calc-default-formula-arglist calc-graph-yvalue)
  704. (setq math-arglist (sort math-arglist 'string-lessp))
  705. (or (cdr math-arglist)
  706. (error "%s does not contain enough unassigned variables" calc-graph-yname))
  707. (and (cdr (cdr math-arglist))
  708. (error "%s contains too many variables: %s" calc-graph-yname math-arglist))
  709. (setq calc-graph-yvalue (math-multi-subst calc-graph-yvalue
  710. (mapcar 'math-build-var-name
  711. math-arglist)
  712. '((var DUMMY var-DUMMY)
  713. (var DUMMY2 var-DUMMY2))))))
  714. (if (setq calc-graph-xvec (eq (car-safe calc-graph-xvalue) 'vec))
  715. (setq calc-graph-numsteps (1- (length calc-graph-xvalue)))
  716. (if (and (eq (car-safe calc-graph-xvalue) 'intv)
  717. (math-constp calc-graph-xvalue))
  718. (setq calc-graph-numsteps calc-graph-resolution
  719. calc-graph-xvalue (calcFunc-index calc-graph-numsteps
  720. (nth 2 calc-graph-xvalue)
  721. (math-div (math-sub (nth 3 calc-graph-xvalue)
  722. (nth 2 calc-graph-xvalue))
  723. (1- calc-graph-numsteps))))
  724. (error "%s is not a suitable basis for %s"
  725. calc-graph-xname calc-graph-yname)))
  726. (if (eq (car-safe calc-graph-y3value) 'vec)
  727. (setq calc-graph-numsteps3 (1- (length calc-graph-y3value)))
  728. (if (and (eq (car-safe calc-graph-y3value) 'intv)
  729. (math-constp calc-graph-y3value))
  730. (setq calc-graph-numsteps3 calc-graph-resolution
  731. calc-graph-y3value (calcFunc-index calc-graph-numsteps3
  732. (nth 2 calc-graph-y3value)
  733. (math-div (math-sub (nth 3 calc-graph-y3value)
  734. (nth 2 calc-graph-y3value))
  735. (1- calc-graph-numsteps3))))
  736. (error "%s is not a suitable basis for %s"
  737. calc-graph-y3name calc-graph-yname)))
  738. (setq calc-graph-xp nil
  739. calc-graph-yp nil
  740. calc-graph-zp nil
  741. calc-graph-xvec t)
  742. (setq math-working-step 0)
  743. (while (setq calc-graph-xvalue (cdr calc-graph-xvalue))
  744. (setq calc-graph-xp (nconc calc-graph-xp (make-list (1+ calc-graph-numsteps3) (car calc-graph-xvalue)))
  745. calc-graph-yp (nconc calc-graph-yp (cons 0 (copy-sequence (cdr calc-graph-y3value))))
  746. calc-graph-zp (cons '(skip) calc-graph-zp)
  747. calc-graph-y3step calc-graph-y3value
  748. var-DUMMY (car calc-graph-xvalue)
  749. math-working-step-2 0
  750. math-working-step (1+ math-working-step))
  751. (while (setq calc-graph-y3step (cdr calc-graph-y3step))
  752. (setq math-working-step-2 (1+ math-working-step-2)
  753. var-DUMMY2 (car calc-graph-y3step)
  754. calc-graph-zp (cons (math-evaluate-expr calc-graph-yvalue) calc-graph-zp))))
  755. (setq calc-graph-zp (nreverse calc-graph-zp)
  756. calc-graph-numsteps (1- (* calc-graph-numsteps (1+ calc-graph-numsteps3))))))
  757. (defun calc-graph-format-data ()
  758. (if (math-contains-sdev-p calc-graph-yp)
  759. (let ((yp calc-graph-yp))
  760. (setq calc-graph-yp (cons 'vec (mapcar 'math-get-value (cdr yp))))
  761. (setq calc-graph-zp (cons 'vec (mapcar 'math-get-sdev (cdr yp))))))
  762. (while (<= (setq calc-graph-stepcount (1+ calc-graph-stepcount)) calc-graph-numsteps)
  763. (if calc-graph-xvec
  764. (setq calc-graph-xp (cdr calc-graph-xp)
  765. calc-graph-xval (car calc-graph-xp)
  766. calc-graph-yp (cdr calc-graph-yp)
  767. calc-graph-yval (car calc-graph-yp)
  768. calc-graph-zp (cdr calc-graph-zp)
  769. calc-graph-zval (car calc-graph-zp))
  770. (if calc-graph-yvec
  771. (setq calc-graph-xval calc-graph-xvalue
  772. calc-graph-xvalue (math-add calc-graph-xvalue calc-graph-xstep)
  773. calc-graph-yp (cdr calc-graph-yp)
  774. calc-graph-yval (car calc-graph-yp))
  775. (setq calc-graph-xval (car (car calc-graph-yp))
  776. calc-graph-yval (cdr (car calc-graph-yp))
  777. calc-graph-yp (cdr calc-graph-yp))
  778. (if (or (not calc-graph-yp)
  779. (and calc-graph-xhigh (equal calc-graph-xval calc-graph-xhigh)))
  780. (setq calc-graph-numsteps 0))))
  781. (if calc-graph-is-splot
  782. (if (and (eq (car-safe calc-graph-zval) 'calcFunc-xyz)
  783. (= (length calc-graph-zval) 4))
  784. (setq calc-graph-xval (nth 1 calc-graph-zval)
  785. calc-graph-yval (nth 2 calc-graph-zval)
  786. calc-graph-zval (nth 3 calc-graph-zval)))
  787. (if (and (eq (car-safe calc-graph-yval) 'calcFunc-xyz)
  788. (= (length calc-graph-yval) 4))
  789. (progn
  790. (or calc-graph-surprise-splot
  791. (with-current-buffer (get-buffer-create "*Gnuplot Temp*")
  792. (save-excursion
  793. (goto-char (point-max))
  794. (re-search-backward "^plot[ \t]")
  795. (insert "set parametric\ns")
  796. (setq calc-graph-surprise-splot t))))
  797. (setq calc-graph-xval (nth 1 calc-graph-yval)
  798. calc-graph-zval (nth 3 calc-graph-yval)
  799. calc-graph-yval (nth 2 calc-graph-yval)))
  800. (if (and (eq (car-safe calc-graph-yval) 'calcFunc-xy)
  801. (= (length calc-graph-yval) 3))
  802. (setq calc-graph-xval (nth 1 calc-graph-yval)
  803. calc-graph-yval (nth 2 calc-graph-yval)))))
  804. (if (and (Math-realp calc-graph-xval)
  805. (Math-realp calc-graph-yval)
  806. (or (not calc-graph-zval) (Math-realp calc-graph-zval)))
  807. (progn
  808. (setq calc-graph-blank nil
  809. calc-graph-non-blank t)
  810. (if (Math-integerp calc-graph-xval)
  811. (insert (math-format-number calc-graph-xval))
  812. (if (eq (car calc-graph-xval) 'frac)
  813. (setq calc-graph-xval (math-float calc-graph-xval)))
  814. (insert (math-format-number (nth 1 calc-graph-xval))
  815. "e" (int-to-string (nth 2 calc-graph-xval))))
  816. (insert " ")
  817. (if (Math-integerp calc-graph-yval)
  818. (insert (math-format-number calc-graph-yval))
  819. (if (eq (car calc-graph-yval) 'frac)
  820. (setq calc-graph-yval (math-float calc-graph-yval)))
  821. (insert (math-format-number (nth 1 calc-graph-yval))
  822. "e" (int-to-string (nth 2 calc-graph-yval))))
  823. (if calc-graph-zval
  824. (progn
  825. (insert " ")
  826. (if (Math-integerp calc-graph-zval)
  827. (insert (math-format-number calc-graph-zval))
  828. (if (eq (car calc-graph-zval) 'frac)
  829. (setq calc-graph-zval (math-float calc-graph-zval)))
  830. (insert (math-format-number (nth 1 calc-graph-zval))
  831. "e" (int-to-string (nth 2 calc-graph-zval))))))
  832. (insert "\n"))
  833. (and (not (equal calc-graph-zval '(skip)))
  834. (boundp 'var-PlotRejects)
  835. (eq (car-safe var-PlotRejects) 'vec)
  836. (nconc var-PlotRejects
  837. (list (list 'vec
  838. calc-graph-curve-num
  839. calc-graph-stepcount
  840. calc-graph-xval calc-graph-yval)))
  841. (calc-refresh-evaltos 'var-PlotRejects))
  842. (or calc-graph-blank
  843. (progn
  844. (insert "\n")
  845. (setq calc-graph-blank t))))))
  846. (defun calc-temp-file-name (num)
  847. (while (<= (length calc-graph-file-cache) (1+ num))
  848. (setq calc-graph-file-cache (nconc calc-graph-file-cache (list nil))))
  849. (car (or (nth (1+ num) calc-graph-file-cache)
  850. (setcar (nthcdr (1+ num) calc-graph-file-cache)
  851. (list (make-temp-file
  852. (concat calc-gnuplot-tempfile
  853. (if (<= num 0)
  854. (char-to-string (- ?A num))
  855. (int-to-string num))))
  856. nil)))))
  857. (defun calc-graph-delete-temps ()
  858. (while calc-graph-file-cache
  859. (and (car calc-graph-file-cache)
  860. (file-exists-p (car (car calc-graph-file-cache)))
  861. (condition-case err
  862. (delete-file (car (car calc-graph-file-cache)))
  863. (error nil)))
  864. (setq calc-graph-file-cache (cdr calc-graph-file-cache))))
  865. (defun calc-graph-kill-hook ()
  866. (calc-graph-delete-temps))
  867. (defun calc-graph-show-tty (output)
  868. "Default calc-gnuplot-plot-command for \"tty\" output mode.
  869. This is useful for tek40xx and other graphics-terminal types."
  870. (call-process-region 1 1 shell-file-name
  871. nil calc-gnuplot-buffer nil
  872. "-c" (format "cat %s >/dev/tty; rm %s" output output)))
  873. (defvar calc-dumb-map nil
  874. "The keymap for the \"dumb\" terminal plot.")
  875. (defun calc-graph-show-dumb (&optional output)
  876. "Default calc-gnuplot-plot-command for Pinard's \"dumb\" terminal type.
  877. This \"dumb\" driver will be present in Gnuplot 3.0."
  878. (interactive)
  879. (save-window-excursion
  880. (switch-to-buffer calc-gnuplot-buffer)
  881. (delete-other-windows)
  882. (goto-char calc-gnuplot-trail-mark)
  883. (or (search-forward "\f" nil t)
  884. (sleep-for 1))
  885. (goto-char (point-max))
  886. (re-search-backward "\f\\|^[ \t]+\\^$\\|G N U P L O T")
  887. (if (looking-at "\f")
  888. (progn
  889. (forward-char 1)
  890. (if (eolp) (forward-line 1))
  891. (or (calc-graph-find-command "time")
  892. (calc-graph-find-command "title")
  893. (calc-graph-find-command "ylabel")
  894. (let ((pt (point)))
  895. (insert-before-markers (format "(%s)" (current-time-string)))
  896. (goto-char pt)))
  897. (set-window-start (selected-window) (point))
  898. (goto-char (point-max)))
  899. (end-of-line)
  900. (backward-char 1)
  901. (recenter '(4)))
  902. (or calc-dumb-map
  903. (progn
  904. (setq calc-dumb-map (make-sparse-keymap))
  905. (define-key calc-dumb-map "\n" 'scroll-up-command)
  906. (define-key calc-dumb-map " " 'scroll-up-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