From 9822748dfbdb99f1ea534e695e818d7533920a61 Mon Sep 17 00:00:00 2001 From: mfrasca Date: Sun, 28 Jun 2020 16:24:54 -0500 Subject: [PATCH] org-plot/gnuplot-to-grid-data: code review for speed and readability * lisp/org-plot.el (org-plot/gnuplot-to-grid-data): partial rewrite. Optimizing for speed and readability: preprocessing data in order to simplify removal on non-plotting columns; using available functions like set-difference and org-remove-by-index; loop over elements instead of counting indices and invoking `nth' (in a double loop). --- lisp/org-plot.el | 81 +++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 45 deletions(-) diff --git a/lisp/org-plot.el b/lisp/org-plot.el index bf81d3c37..38749c069 100644 --- a/lisp/org-plot.el +++ b/lisp/org-plot.el @@ -130,53 +130,44 @@ Pass PARAMS through to `orgtbl-to-generic' when exporting TABLE." (defun org-plot/gnuplot-to-grid-data (table data-file params) "Export the data in TABLE to DATA-FILE for gnuplot. This means in a format appropriate for grid plotting by gnuplot. -PARAMS specifies which columns of TABLE should be plotted as independent -and dependent variables." - (interactive) - (let* ((ind (- (plist-get params :ind) 1)) - (deps (if (plist-member params :deps) - (mapcar (lambda (val) (- val 1)) (plist-get params :deps)) - (let (collector) - (dotimes (col (length (nth 0 table))) - (setf collector (cons col collector))) - collector))) - (counter 0) - row-vals) - (when (>= ind 0) ;; collect values of ind col - (setf row-vals (mapcar (lambda (row) (setf counter (+ 1 counter)) - (cons counter (nth ind row))) - table))) - (when (or deps (>= ind 0)) ;; remove non-plotting columns - (setf deps (delq ind deps)) - (setf table (mapcar (lambda (row) - (dotimes (col (length row)) - (unless (memq col deps) - (setf (nth col row) nil))) - (delq nil row)) - table))) +PARAMS specifies which columns of TABLE should be plotted as +independent and dependent variables. Return the ind-column, as +list of (cons 0-based-row-num . cell-value)." + (let* ((last-col (1- (length (car table)))) + (ind (1- (plist-get params :ind))) + (deps (delq ind (if (plist-member params :deps) + (mapcar #'1- (plist-get params :deps)) + (number-sequence 0 last-col)))) + (skip-deps (set-difference + (number-sequence 0 last-col) + deps)) + (row-vals ; the return value - indexed values from the ind column + (unless (< ind 0) + (let ((i -1)) (mapcar (lambda (row) + (incf i) + (cons i (nth ind row))) + table))))) + ;; remove non-plotting columns + (setq table (mapcar (lambda (row) + (org-remove-by-index row skip-deps)) + table)) ;; write table to gnuplot grid datafile format (with-temp-file data-file - (let ((num-rows (length table)) (num-cols (length (nth 0 table))) - (gnuplot-row (lambda (col row value) - (setf col (+ 1 col)) (setf row (+ 1 row)) - (format "%f %f %f\n%f %f %f\n" - col (- row 0.5) value ;; lower edge - col (+ row 0.5) value))) ;; upper edge - front-edge back-edge) - (dotimes (col num-cols) - (dotimes (row num-rows) - (setf back-edge - (concat back-edge - (funcall gnuplot-row (- col 1) row - (string-to-number (nth col (nth row table)))))) - (setf front-edge - (concat front-edge - (funcall gnuplot-row col row - (string-to-number (nth col (nth row table))))))) - ;; only insert once per row - (insert back-edge) (insert "\n") ;; back edge - (insert front-edge) (insert "\n") ;; front edge - (setf back-edge "") (setf front-edge "")))) + (let ((gnuplot-row (lambda (c r value) + (format "%f %f %s\n%f %f %s\n" + c (+ r 0.5) value + c (+ r 1.5) value)))) + (dotimes (c (length (car table))) + (let ((column (mapcar (lambda (row) (nth c row)) table)) + (r 0) + front-edge back-edge) + (dolist (cell column) + (setq back-edge (concat back-edge + (funcall gnuplot-row c r cell))) + (setq front-edge (concat front-edge + (funcall gnuplot-row (1+ c) r cell))) + (incf r)) + (insert (concat back-edge "\n" front-edge "\n")))))) row-vals)) (defun org-plot/gnuplot-script (data-file num-cols params &optional preface) -- 2.20.1