emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* WIP: Org-plot work
@ 2020-07-08 21:36 TEC
  2020-07-30  5:17 ` TEC
  0 siblings, 1 reply; 8+ messages in thread
From: TEC @ 2020-07-08 21:36 UTC (permalink / raw)
  To: org-mode-email; +Cc: Eric Schulte

[-- Attachment #1: Type: text/plain, Size: 0 bytes --]



[-- Attachment #2.1: Type: text/plain, Size: 410 bytes --]

Hi All,

I've just finished re-working my modifications to org-plot into 
what I hope is a
form that may (in 9.5?) be merged at some point.
I stayed up later that I wanted getting this finished, so I'll 
save the monolouge
on what I've done for later, but I thought I'd share the current 
state of my
efforts for anyone interested.

If that's you, please let me know what you think :)

All the best,

Timothy.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2.2: 0001-Replace-inconsistent-indentation-in-org-plot.patch --]
[-- Type: text/x-patch, Size: 1414 bytes --]

From 28a7513494f17be0b2219482ebc55f0ce22a0c67 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 8 Jul 2020 18:34:46 +0800
Subject: [PATCH 1/8] Replace inconsistent indentation in org-plot Only 6 of
 355 lines used spaces instead of tabs. Change those 6 lines in
 `org-plot/gnuplot' to use tabs.

---
 lisp/org-plot.el | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/lisp/org-plot.el b/lisp/org-plot.el
index a23195d2a..b211e0403 100644
--- a/lisp/org-plot.el
+++ b/lisp/org-plot.el
@@ -333,12 +333,12 @@ line directly before or after the table."
       (with-temp-buffer
 	(if (plist-get params :script)	; user script
 	    (progn (insert
-                    (org-plot/gnuplot-script data-file num-cols params t))
-                   (insert "\n")
-                   (insert-file-contents (plist-get params :script))
-                   (goto-char (point-min))
-                   (while (re-search-forward "\\$datafile" nil t)
-                     (replace-match data-file nil nil)))
+		    (org-plot/gnuplot-script data-file num-cols params t))
+		   (insert "\n")
+		   (insert-file-contents (plist-get params :script))
+		   (goto-char (point-min))
+		   (while (re-search-forward "\\$datafile" nil t)
+		     (replace-match data-file nil nil)))
 	  (insert (org-plot/gnuplot-script data-file num-cols params)))
 	;; Graph table.
 	(gnuplot-mode)
-- 
2.27.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2.3: 0002-Add-new-org-plot-argument-transpose.patch --]
[-- Type: text/x-patch, Size: 2551 bytes --]

From 495307540ff757b8b4f6f756e456b0bed90801a0 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 8 Jul 2020 19:26:07 +0800
Subject: [PATCH 2/8] Add new org-plot argument, transpose By modifying
 `org-plot/add-options-to-plist' and `org-plot/gnuplot' now #+PLOT recognises
 a transpose:{yes,y,t,*} argument which performs a basic transposition of the
 table data prior to processing. This is rather useful in some plot types like
 radar charts.

---
 lisp/org-plot.el | 41 +++++++++++++++++++++++++++--------------
 1 file changed, 27 insertions(+), 14 deletions(-)

diff --git a/lisp/org-plot.el b/lisp/org-plot.el
index b211e0403..25a0f605b 100644
--- a/lisp/org-plot.el
+++ b/lisp/org-plot.el
@@ -50,19 +50,21 @@
   "Parse an OPTIONS line and set values in the property list P.
 Returns the resulting property list."
   (when options
-    (let ((op '(("type"    . :plot-type)
-		("script"  . :script)
-		("line"    . :line)
-		("set"     . :set)
-		("title"   . :title)
-		("ind"     . :ind)
-		("deps"    . :deps)
-		("with"    . :with)
-		("file"    . :file)
-		("labels"  . :labels)
-		("map"     . :map)
-		("timeind" . :timeind)
-		("timefmt" . :timefmt)))
+    (let ((op '(("type"      . :plot-type)
+		("script"    . :script)
+		("line"      . :line)
+		("set"       . :set)
+		("title"     . :title)
+		("ind"       . :ind)
+		("deps"      . :deps)
+		("with"      . :with)
+		("file"      . :file)
+		("labels"    . :labels)
+		("map"       . :map)
+		("timeind"   . :timeind)
+		("timefmt"   . :timefmt)
+		("trans"     . :transpose)
+		("transpose" . :transpose)))
 	  (multiples '("set" "line"))
 	  (regexp ":\\([\"][^\"]+?[\"]\\|[(][^)]+?[)]\\|[^ \t\n\r;,.]*\\)")
 	  (start 0))
@@ -289,7 +291,18 @@ line directly before or after the table."
 	(setf params (plist-put params (car pair) (cdr pair)))))
     ;; collect table and table information
     (let* ((data-file (make-temp-file "org-plot"))
-	   (table (org-table-to-lisp))
+	   (table (let ((tbl (org-table-to-lisp)))
+		    (when (pcase (plist-get params :transpose)
+			    ('y   t)
+			    ('yes t)
+			    ('t   t))
+		      (if (memq 'hline tbl)
+			  (setq tbl (apply #'cl-mapcar #'list tbl))
+			;; When present, remove hlines as they can't (currentily) be easily transposed.
+			(setq tbl (apply #'cl-mapcar #'list
+					 (remove 'hline tbl)))
+			(push 'hline (cdr tbl))))
+		    tbl))
 	   (num-cols (length (if (eq (nth 0 table) 'hline) (nth 1 table)
 			       (nth 0 table)))))
       (run-with-idle-timer 0.1 nil #'delete-file data-file)
-- 
2.27.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2.4: 0003-Add-org-plot-custom-to-add-content-to-all-plots.patch --]
[-- Type: text/x-patch, Size: 1857 bytes --]

From 253b9d22ebee26ae89127de9071cac0ee6bfbd23 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 8 Jul 2020 22:26:21 +0800
Subject: [PATCH 3/8] Add org-plot custom to add content to all plots Adds a
 new custom: `org-plot/gnuplot-script-preamble' which can be either a string
 or function (which is called to produce a string). This allows for the user
 to add gnuplot script to the code generated by `org-plot/gnuplot', setting
 say the font/colour-scheme, default precision, etc.

---
 lisp/org-plot.el | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/lisp/org-plot.el b/lisp/org-plot.el
index 25a0f605b..5a36fd624 100644
--- a/lisp/org-plot.el
+++ b/lisp/org-plot.el
@@ -181,6 +181,13 @@ and dependent variables."
 	  (setf back-edge "") (setf front-edge ""))))
     row-vals))
 
+(defcustom org-plot/gnuplot-script-preamble ""
+  "String or function which provides content to be inserted into the GNUPlot
+script before the plot command. Not that this is in addition to, not instead of
+other content generated in `org-plot/gnuplot-script'."
+  :group 'org-plot
+  :type '(choice string function))
+
 (defun org-plot/gnuplot-script (data-file num-cols params &optional preface)
   "Write a gnuplot script to DATA-FILE respecting the options set in PARAMS.
 NUM-COLS controls the number of columns plotted in a 2-d plot.
@@ -213,6 +220,12 @@ manner suitable for prepending to a user-specified script."
     (when file				; output file
       (funcall ats (format "set term %s" (file-name-extension file)))
       (funcall ats (format "set output '%s'" file)))
+
+    (funcall ats
+	     (if (stringp org-plot/gnuplot-script-preamble)
+		 org-plot/gnuplot-script-preamble
+	       (org-plot/gnuplot-script-preamble)))
+
     (pcase type				; type
       (`2d ())
       (`3d (when map (funcall ats "set map")))
-- 
2.27.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2.5: 0004-Extract-org-plot-presets-to-custom-variable.patch --]
[-- Type: text/x-patch, Size: 4165 bytes --]

From 4db0363ed85c02ec7938450083cc9013e0c00138 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Thu, 9 Jul 2020 04:27:18 +0800
Subject: [PATCH 4/8] Extract org-plot presets to custom variable. Prior to
 this commit, the plot presets type:{2d,3d,grid} were hardcoded in
 `org-plot/gnuplot-script'. By extracting them to a custom variable, users are
 able to create their own presets for frequently used setups. Note that while
 this moves the most significant hardcoding of the 2d, 3d, and grid types in
 `org-plot/gnuplot-script', there are still a few minor fragments that I am
 not sure how to best address.

---
 lisp/org-plot.el | 71 ++++++++++++++++++++++++++++++++----------------
 1 file changed, 48 insertions(+), 23 deletions(-)

diff --git a/lisp/org-plot.el b/lisp/org-plot.el
index 5a36fd624..95ed17f8e 100644
--- a/lisp/org-plot.el
+++ b/lisp/org-plot.el
@@ -188,6 +188,49 @@ other content generated in `org-plot/gnuplot-script'."
   :group 'org-plot
   :type '(choice string function))
 
+(defcustom org-plot/preset-plot-types
+  '((2d (lambda (data-file num-cols params plot-str)
+	  (let* ((type (plist-get params :plot-type))
+		 (with (if (eq type 'grid) 'pm3d (plist-get params :with)))
+		 (ind (plist-get params :ind))
+		 (deps (if (plist-member params :deps) (plist-get params :deps)))
+		 (text-ind (plist-get params :textind))
+		 (col-labels (plist-get params :labels))
+		 res)
+	    (dotimes (col num-cols res)
+	      (unless (and (eq type '2d)
+			   (or (and ind (equal (1+ col) ind))
+			       (and deps (not (member (1+ col) deps)))))
+		(setf res
+		      (cons
+		       (format plot-str data-file
+			       (or (and ind (> ind 0)
+					(not text-ind)
+					(format "%d:" ind)) "")
+			       (1+ col)
+			       (if text-ind (format ":xticlabel(%d)" ind) "")
+			       with
+			       (or (nth col col-labels)
+				   (format "%d" (1+ col))))
+		       res)))))))
+    (3d (lambda (data-file num-cols params plot-str)
+	  (let* ((type (plist-get params :plot-type))
+		 (with (if (eq type 'grid) 'pm3d (plist-get params :with))))
+	    (list (format "'%s' matrix with %s title ''"
+			  data-file with)))))
+    (grid (lambda (data-file num-cols params plot-str)
+	    (let* ((type (plist-get params :plot-type))
+		   (with (if (eq type 'grid) 'pm3d (plist-get params :with))))
+	    (list (format "'%s' with %s title ''"
+			  data-file with))))))
+  "List of plot presets with the type name as the car, and a function
+which yeilds plot-lines (a list of strings) as the cdr.
+The parameters of `org-plot/gnuplot-script' and PLOT-STR are passed to
+that function. i.e. it is called with the following arguments:
+  DATA-FILE NUM-COLS PARAMS PLOT-STR"
+  :group 'org-plot
+  :type '(alist :value-type (symbol group)))
+
 (defun org-plot/gnuplot-script (data-file num-cols params &optional preface)
   "Write a gnuplot script to DATA-FILE respecting the options set in PARAMS.
 NUM-COLS controls the number of columns plotted in a 2-d plot.
@@ -254,29 +297,11 @@ manner suitable for prepending to a user-specified script."
 			   (or timefmt	; timefmt passed to gnuplot
 			       "%Y-%m-%d-%H:%M:%S") "\"")))
     (unless preface
-      (pcase type			; plot command
-	(`2d (dotimes (col num-cols)
-	       (unless (and (eq type '2d)
-			    (or (and ind (equal (1+ col) ind))
-				(and deps (not (member (1+ col) deps)))))
-		 (setf plot-lines
-		       (cons
-			(format plot-str data-file
-				(or (and ind (> ind 0)
-					 (not text-ind)
-					 (format "%d:" ind)) "")
-				(1+ col)
-				(if text-ind (format ":xticlabel(%d)" ind) "")
-				with
-				(or (nth col col-labels)
-				    (format "%d" (1+ col))))
-			plot-lines)))))
-	(`3d
-	 (setq plot-lines (list (format "'%s' matrix with %s title ''"
-					data-file with))))
-	(`grid
-	 (setq plot-lines (list (format "'%s' with %s title ''"
-					data-file with)))))
+      (let ((type-func (cadr (assoc type org-plot/preset-plot-types))))
+	(when type-func
+	  (setq plot-lines
+		(funcall type-func data-file num-cols params plot-str))))
+
       (funcall ats
 	       (concat plot-cmd " " (mapconcat #'identity
 					       (reverse plot-lines)
-- 
2.27.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2.6: 0005-Add-some-utility-functions-to-org-plot-axis-ticks.patch --]
[-- Type: text/x-patch, Size: 5860 bytes --]

From 9563381eaa15ae0f9714709d4c1de3bcf3e4edda Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Thu, 9 Jul 2020 04:47:40 +0800
Subject: [PATCH 5/8] Add some utility functions to org-plot axis ticks It can
 be useful to attempt to determine a sensible number of ticks to have on an
 axis. This turns out to be harder than expected, and so a number of functions
 are used to attempt to do so. The essence of the method used, is to round
 values and find their prime decompositions. From this we try to select the
 most common components to give a reasonable step size. We also add a 'ticks'
 parameter for manually setting the number of ticks, and (y)min/max parameters
 similarly.

---
 lisp/org-plot.el | 100 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/lisp/org-plot.el b/lisp/org-plot.el
index 95ed17f8e..0bc7ae309 100644
--- a/lisp/org-plot.el
+++ b/lisp/org-plot.el
@@ -63,6 +63,11 @@ Returns the resulting property list."
 		("map"       . :map)
 		("timeind"   . :timeind)
 		("timefmt"   . :timefmt)
+		("min"       . :ymin)
+		("max"       . :ymax)
+		("ymin"      . :ymin)
+		("xmax"      . :xmax)
+		("ticks"     . :ticks)
 		("trans"     . :transpose)
 		("transpose" . :transpose)))
 	  (multiples '("set" "line"))
@@ -181,6 +186,101 @@ and dependent variables."
 	  (setf back-edge "") (setf front-edge ""))))
     row-vals))
 
+(defun org--plot/values-stats (nums &optional hard-min hard-max)
+  "From a list of NUMS return a plist containing some rudamentry statistics on the
+values, namely regarding the range."
+  (let* ((minimum (or hard-min (apply #'min nums)))
+	 (maximum (or hard-max (apply #'max nums)))
+	 (range (- maximum minimum))
+	 (rangeOrder (ceiling (- 1 (log10 range))))
+	 (range-factor (expt 10 rangeOrder))
+	 (nice-min (/ (float (floor (* minimum range-factor))) range-factor))
+	 (nice-max (/ (float (ceiling (* maximum range-factor))) range-factor)))
+    `(:min ,minimum :max ,maximum :range ,range
+      :range-factor ,range-factor
+      :nice-min ,nice-min :nice-max ,nice-max :nice-range ,(- nice-max nice-min))))
+
+(defun org--plot/sensible-tick-num (table &optional hard-min hard-max)
+  "From a the values in a TABLE of data, attempt to guess an appropriate number of ticks."
+  (let* ((row-data
+	  (mapcar (lambda (row) (org--plot/values-stats
+			    (mapcar #'string-to-number (cdr row))
+			    hard-min
+			    hard-max)) table))
+	 (row-normalised-ranges (mapcar (lambda (r-data)
+					  (let ((val (round (*
+							     (plist-get r-data :range-factor)
+							     (plist-get r-data :nice-range)))))
+					    (if (= (% val 10) 0) (/ val 10) val)))
+					row-data))
+	 (range-prime-decomposition (mapcar #'org--plot/prime-factors row-normalised-ranges))
+	 (weighted-factors (sort (apply #'org--plot/merge-alists #'+ 0
+					(mapcar (lambda (factors) (org--plot/item-frequencies factors t))
+						range-prime-decomposition))
+				 (lambda (a b) (> (cdr a) (cdr b))))))
+    (apply #'* (org--plot/nice-frequency-pick weighted-factors))))
+
+(defun org--plot/nice-frequency-pick (frequencies)
+  "From a list of frequences, try to sensibly pick a sample of the most frequent."
+  ;; TODO this mosly works decently, but counld do with some tweaking to work more consistently.
+  (case (length frequencies)
+    (1 (list (car (nth 0 frequencies))))
+    (2 (if (<= 3 (/ (cdr (nth 0 frequencies))
+		    (cdr (nth 1 frequencies))))
+	   (make-list 2
+		      (car (nth 0 frequencies)))
+	 (list (car (nth 0 frequencies))
+	       (car (nth 1 frequencies)))))
+    (t
+     (let* ((total-count (apply #'+ (mapcar #'cdr frequencies)))
+	    (n-freq (mapcar (lambda (freq) `(,(car freq) . ,(/ (float (cdr freq)) total-count))) frequencies))
+	    (f-pick (list (car (car n-freq))))
+	    (1-2-ratio (/ (cdr (nth 0 n-freq))
+			  (cdr (nth 1 n-freq))))
+	    (2-3-ratio (/ (cdr (nth 1 n-freq))
+			  (cdr (nth 2 n-freq))))
+	    (1-3-ratio (* 1-2-ratio 2-3-ratio))
+	    (1-val (car (nth 0 n-freq)))
+	    (2-val (car (nth 1 n-freq)))
+	    (3-val (car (nth 2 n-freq))))
+       (when (> 1-2-ratio 4) (push 1-val f-pick))
+       (when (and (< 1-2-ratio 2-val)
+		  (< (* (apply #'* f-pick) 2-val) 30))
+	 (push 2-val f-pick))
+       (when (and (< 1-3-ratio 3-val)
+		  (< (* (apply #'* f-pick) 3-val) 30))
+	 (push 3-val f-pick))
+       f-pick))))
+
+(defun org--plot/merge-alists (function default alist1 alist2 &rest alists)
+  "Using FUNCTION, combine the elements of all given ALISTS. When an element is
+only present in one alist, DEFAULT is used as the second argument for the FUNCTION."
+  (when (> (length alists) 0)
+    (setq alist2 (apply #'org--plot/merge-alists function default alist2 alists)))
+  (flet ((keys (alist) (mapcar #'car alist))
+	 (lookup (key alist) (or (cdr (assoc key alist)) default)))
+    (loop with keys = (union (keys alist1) (keys alist2) :test 'equal)
+	  for k in keys collect
+	  (cons k (funcall function (lookup k alist1) (lookup k alist2))))))
+
+(defun org--plot/item-frequencies (values &optional normalise)
+  "Return an alist indicating the frequency of values in VALUES list."
+  (let ((normaliser (if normalise (float (length values)) 1)))
+    (cl-loop for (n . m) in (seq-group-by #'identity values)
+	     collect (cons n (/ (length m) normaliser)))))
+
+(defun org--plot/prime-factors (value)
+  "Return the prime decomposition of VALUE, e.g. for 12, '(3 2 2)"
+  (let ((factors '(1)) (i 1))
+    (while (/= 1 value)
+      (setq i (1+ i))
+      (when (eq 0 (% value i))
+	(push i factors)
+	(setq value (/ value i))
+	(setq i (1- i))
+	))
+    (subseq factors 0 -1)))
+
 (defcustom org-plot/gnuplot-script-preamble ""
   "String or function which provides content to be inserted into the GNUPlot
 script before the plot command. Not that this is in addition to, not instead of
-- 
2.27.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2.7: 0006-Allow-for-customisation-of-org-plot-s-term.patch --]
[-- Type: text/x-patch, Size: 1938 bytes --]

From 2d88ddd8d4bb2144bfe7e2608d0379794b51aaf6 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Thu, 9 Jul 2020 05:00:03 +0800
Subject: [PATCH 6/8] Allow for customisation of org-plot's term Adds a custom
 variable (used in `org-plot/gnuplot-script') which allows the user to tweak
 the gnuplot term settings. This allows for setting characteristics such as
 default size, or background colour.

---
 lisp/org-plot.el | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/lisp/org-plot.el b/lisp/org-plot.el
index 0bc7ae309..d6146d23d 100644
--- a/lisp/org-plot.el
+++ b/lisp/org-plot.el
@@ -331,6 +331,13 @@ that function. i.e. it is called with the following arguments:
   :group 'org-plot
   :type '(alist :value-type (symbol group)))
 
+(defcustom org-plot/gnuplot-term-extra ""
+  "String or function which provides the extra term options.
+E.g. a value of \"size 1050,650\" would cause
+\"set term ... size 1050,650\" to be used."
+  :group 'org-plot
+  :type '(choice string function))
+
 (defun org-plot/gnuplot-script (data-file num-cols params &optional preface)
   "Write a gnuplot script to DATA-FILE respecting the options set in PARAMS.
 NUM-COLS controls the number of columns plotted in a 2-d plot.
@@ -360,8 +367,15 @@ manner suitable for prepending to a user-specified script."
 	 ;; ats = add-to-script
 	 (ats (lambda (line) (setf script (concat script "\n" line))))
 	 plot-lines)
-    (when file				; output file
-      (funcall ats (format "set term %s" (file-name-extension file)))
+
+
+    ;; handle output file, background, and size
+    (funcall ats (format "set term %s %s"
+			 (if file (file-name-extension file) "GNUTERM")
+			 (if (stringp org-plot/gnuplot-term-extra)
+			     org-plot/gnuplot-term-extra
+			   (org-plot/gnuplot-term-extra))))
+    (when file ; output file
       (funcall ats (format "set output '%s'" file)))
 
     (funcall ats
-- 
2.27.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2.8: 0007-Org-plot-tweak-term-and-preamble-custom-vars.patch --]
[-- Type: text/x-patch, Size: 2196 bytes --]

From c154151fbc3383ff8bcc735542e446c82c18a868 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Thu, 9 Jul 2020 05:05:20 +0800
Subject: [PATCH 7/8] Org-plot: tweak term and preamble custom vars The custom
 variables `org-plot/gnuplot-script-preamble' and
 `org-plot/gnuplot-term-extra' now take the plot type as an argument.

---
 lisp/org-plot.el | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/lisp/org-plot.el b/lisp/org-plot.el
index d6146d23d..3b486fed2 100644
--- a/lisp/org-plot.el
+++ b/lisp/org-plot.el
@@ -284,7 +284,8 @@ only present in one alist, DEFAULT is used as the second argument for the FUNCTI
 (defcustom org-plot/gnuplot-script-preamble ""
   "String or function which provides content to be inserted into the GNUPlot
 script before the plot command. Not that this is in addition to, not instead of
-other content generated in `org-plot/gnuplot-script'."
+other content generated in `org-plot/gnuplot-script'.
+If a function, it is called with the plot type as the argument."
   :group 'org-plot
   :type '(choice string function))
 
@@ -334,7 +335,8 @@ that function. i.e. it is called with the following arguments:
 (defcustom org-plot/gnuplot-term-extra ""
   "String or function which provides the extra term options.
 E.g. a value of \"size 1050,650\" would cause
-\"set term ... size 1050,650\" to be used."
+\"set term ... size 1050,650\" to be used.
+If a function, it is called with the plot type as the argument."
   :group 'org-plot
   :type '(choice string function))
 
@@ -374,14 +376,14 @@ manner suitable for prepending to a user-specified script."
 			 (if file (file-name-extension file) "GNUTERM")
 			 (if (stringp org-plot/gnuplot-term-extra)
 			     org-plot/gnuplot-term-extra
-			   (org-plot/gnuplot-term-extra))))
+			   (org-plot/gnuplot-term-extra type))))
     (when file ; output file
       (funcall ats (format "set output '%s'" file)))
 
     (funcall ats
 	     (if (stringp org-plot/gnuplot-script-preamble)
 		 org-plot/gnuplot-script-preamble
-	       (org-plot/gnuplot-script-preamble)))
+	       (org-plot/gnuplot-script-preamble type)))
 
     (pcase type				; type
       (`2d ())
-- 
2.27.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2.9: 0008-Org-plot-add-radar-plot-type.patch --]
[-- Type: text/x-patch, Size: 5733 bytes --]

From a7af0ff66917f92c735735d88eeccb5019937273 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Thu, 9 Jul 2020 05:21:44 +0800
Subject: [PATCH 8/8] Org-plot: add radar plot type.

---
 lisp/org-plot.el | 138 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 137 insertions(+), 1 deletion(-)

diff --git a/lisp/org-plot.el b/lisp/org-plot.el
index 3b486fed2..c435ef733 100644
--- a/lisp/org-plot.el
+++ b/lisp/org-plot.el
@@ -323,7 +323,9 @@ If a function, it is called with the plot type as the argument."
 	    (let* ((type (plist-get params :plot-type))
 		   (with (if (eq type 'grid) 'pm3d (plist-get params :with))))
 	    (list (format "'%s' with %s title ''"
-			  data-file with))))))
+			  data-file with)))))
+    (radar (lambda (data-file num-cols params plot-str)
+	     (list (org--plot/radar table params)))))
   "List of plot presets with the type name as the car, and a function
 which yeilds plot-lines (a list of strings) as the cdr.
 The parameters of `org-plot/gnuplot-script' and PLOT-STR are passed to
@@ -332,6 +334,140 @@ that function. i.e. it is called with the following arguments:
   :group 'org-plot
   :type '(alist :value-type (symbol group)))
 
+(defvar org--plot/radar-template
+  "### spider plot/chart with gnuplot
+# also known as: radar chart, web chart, star chart, cobweb chart,
+#                radar plot,  web plot,  star plot,  cobweb plot,  etc. ...
+set datafile separator ' '
+set size square
+unset tics
+set angles degree
+set key bmargin center horizontal
+unset border
+
+# Load data and settup
+load \"%s\"
+
+# General settings
+DataColCount = words($Data[1])-1
+AxesCount = |$Data|-HeaderLines
+AngleOffset = 90
+Max = 1
+d=0.1*Max
+Direction = -1   # counterclockwise=1, clockwise = -1
+
+# Tic settings
+TicCount = %s
+TicOffset = 0.1
+TicValue(axis,i) = real(i)*(word($Settings[axis],3)-word($Settings[axis],2)) \\
+	  / word($Settings[axis],4)+word($Settings[axis],2)
+TicLabelPosX(axis,i) = PosX(axis,i/TicCount) + PosY(axis, TicOffset)
+TicLabelPosY(axis,i) = PosY(axis,i/TicCount) - PosX(axis, TicOffset)
+TicLen = 0.03
+TicdX(axis,i) = 0.5*TicLen*cos(alpha(axis)-90)
+TicdY(axis,i) = 0.5*TicLen*sin(alpha(axis)-90)
+
+# Label
+LabOffset = 0.10
+LabX(axis) = PosX(axis+1,Max+2*d) + PosY(axis, LabOffset)
+LabY(axis) = PosY($0+1,Max+2*d)
+
+# Functions
+alpha(axis) = (axis-1)*Direction*360.0/AxesCount+AngleOffset
+PosX(axis,R) = R*cos(alpha(axis))
+PosY(axis,R) = R*sin(alpha(axis))
+Scale(axis,value) = real(value-word($Settings[axis],2))/(word($Settings[axis],3)-word($Settings[axis],2))
+
+# Spider settings
+set style arrow 1 dt 1 lw 1.0 @fgal head filled size 0.06,25     # style for axes
+set style arrow 2 dt 2 lw 0.5 @fgal nohead   # style for weblines
+set style arrow 3 dt 1 lw 1 @fgal nohead     # style for axis tics
+set samples AxesCount
+set isosamples TicCount
+set urange[1:AxesCount]
+set vrange[1:TicCount]
+set style fill transparent solid 0.2
+
+set xrange[-Max-4*d:Max+4*d]
+set yrange[-Max-4*d:Max+4*d]
+plot \\
+    '+' u (0):(0):(PosX($0,Max+d)):(PosY($0,Max+d)) w vec as 1 not, \\
+    $Data u (LabX($0)): \\
+	(LabY($0)):1 every ::HeaderLines w labels center enhanced @fgt not, \\
+    for [i=1:DataColCount] $Data u (PosX($0+1,Scale($0+1,column(i+1)))): \\
+	(PosY($0+1,Scale($0+1,column(i+1)))) every ::HeaderLines w filledcurves lt i title word($Data[1],i+1), \\
+%s
+#    '++' u (PosX($1,$2/TicCount)-TicdX($1,$2/TicCount)): \\
+#        (PosY($1,$2/TicCount)-TicdY($1,$2/TicCount)): \\
+#        (2*TicdX($1,$2/TicCount)):(2*TicdY($1,$2/TicCount)) \\
+#        w vec as 3 not, \\
+### end of code
+")
+
+(defvar org--plot/radar-ticks
+  "    '++' u (PosX($1,$2/TicCount)):(PosY($1,$2/TicCount)): \\
+	(PosX($1+1,$2/TicCount)-PosX($1,$2/TicCount)):  \\
+	(PosY($1+1,$2/TicCount)-PosY($1,$2/TicCount)) w vec as 2 not, \\
+    '++' u (TicLabelPosX(%s,$2)):(TicLabelPosY(%s,$2)): \\
+	(sprintf('%%g',TicValue(%s,$2))) w labels font ',8' @fgat not")
+
+(defvar org--plot/radar-setup-template
+  "# Data
+$Data <<HEREHAVESOMEDATA
+%s
+HEREHAVESOMEDATA
+HeaderLines = 1
+
+# Settings for scale and offset adjustments
+# axis min max tics axisLabelXoff axisLabelYoff
+$Settings <<EOD
+%s
+EOD
+")
+
+(defun org--plot/radar (table params)
+  (let* ((data
+	  (concat "\"" (s-join "\" \"" (plist-get params :labels)) "\""
+		  "\n"
+		  (s-join "\n"
+			  (mapcar (lambda (row)
+				    (format
+				     "\"%s\" %s"
+				     (car row)
+				     (s-join " " (cdr row))))
+				  table))))
+	 (ticks (or (plist-get params :ticks)
+		    (org--plot/sensible-tick-num table
+						 (plist-get params :ymin)
+						 (plist-get params :ymax))))
+	 (settings
+	  (s-join "\n"
+		  (mapcar (lambda (row)
+			    (let ((data (org--plot/values-stats
+					 (mapcar #'string-to-number (cdr row)))))
+			      (format
+			       "\"%s\" %s %s %s"
+			       (car row)
+			       (or (plist-get params :ymin)
+				   (plist-get data :nice-min))
+			       (or (plist-get params :ymax)
+				   (plist-get data :nice-max))
+			       (if (eq ticks 0) 2 ticks)
+			       )))
+			  table)))
+	 (setup-file (make-temp-file "org-plot-setup")))
+    (f-write-text (format org--plot/radar-setup-template data settings)
+		  'utf-8 setup-file)
+    (format org--plot/radar-template
+	    setup-file
+	    (if (eq ticks 0) 2 ticks)
+	    (if (eq ticks 0) ""
+	      (apply #'format org--plot/radar-ticks
+		     (make-list 3 (if (and (plist-get params :ymin)
+					   (plist-get params :ymax))
+				      ;; FIXME multi-drawing of tick labels with "1"
+				      "1" "$1")))))))
+
 (defcustom org-plot/gnuplot-term-extra ""
   "String or function which provides the extra term options.
 E.g. a value of \"size 1050,650\" would cause
-- 
2.27.0


[-- Attachment #2.10.1: Type: text/html, Size: 2356 bytes --]

[-- Attachment #3.1: Type: text/html, Size: 5762 bytes --]

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: WIP: Org-plot work
  2020-07-08 21:36 WIP: Org-plot work TEC
@ 2020-07-30  5:17 ` TEC
  2020-09-05  7:29   ` Bastien
  0 siblings, 1 reply; 8+ messages in thread
From: TEC @ 2020-07-30  5:17 UTC (permalink / raw)
  To: org-mode-email; +Cc: Eric Schulte


I now have a more complete patch set if any maintainers would be 
ready to receive and review it.

TEC <tecosaur@gmail.com> writes:

> Hi All,
>
> I’ve just finished re-working my modifications to org-plot into what I hope is a
> form that may (in 9.5?) be merged at some point.
> I stayed up later that I wanted getting this finished, so I’ll save the monolouge
> on what I’ve done for later, but I thought I’d share the current state of my
> efforts for anyone interested.
>
> If that’s you, please let me know what you think :)
>
> All the best,
>
> Timothy.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: WIP: Org-plot work
  2020-07-30  5:17 ` TEC
@ 2020-09-05  7:29   ` Bastien
  2020-09-05 15:35     ` TEC
  0 siblings, 1 reply; 8+ messages in thread
From: Bastien @ 2020-09-05  7:29 UTC (permalink / raw)
  To: TEC; +Cc: org-mode-email, Mario Frasca, Eric Schulte

Hi Timothy,

TEC <tecosaur@gmail.com> writes:

> I now have a more complete patch set if any maintainers would be
> ready to receive and review it.

Please share it on the list if you feel it's ready for a review.

Also, Mario has been working on org-plot.el too -- see these threads:

https://orgmode.org/list/c7768c14-711e-a719-87d7-8f7ab2317618@anche.no
https://orgmode.org/list/2abe19ad-2237-991d-5325-82b3f870485e@gmail.com
https://orgmode.org/list/d9f86ea0-0ee6-0ff0-219a-e0dbc27e1896@anche.no
https://orgmode.org/list/f55ce1a9-9c96-119f-ad8a-d28ba66e10c2@anche.no
https://orgmode.org/list/2296ccd0-e6eb-5d0b-c5d9-c33b60932374@anche.no

I'm not an org-plot.el user so I cannot comment on the usefulness and
correctness of the code, but perhaps you need to coordinate your work?

That would be for after 9.4.

Thanks!

-- 
 Bastien


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: WIP: Org-plot work
  2020-09-05  7:29   ` Bastien
@ 2020-09-05 15:35     ` TEC
  2020-09-06  5:34       ` Bastien
  0 siblings, 1 reply; 8+ messages in thread
From: TEC @ 2020-09-05 15:35 UTC (permalink / raw)
  To: Bastien; +Cc: org-mode-email, Mario Frasca, Eric Schulte


Bastien <bzg@gnu.org> writes:

> Please share it on the list if you feel it's ready for a review.

Well, I'm pretty sure it needs further tweaks, but I think that the bulk
of the work would benefit from review at this point --- should I send it
in?

> Also, Mario has been working on org-plot.el too

Ah yes, well if Mario is interested I'm certainly open to such an idea :)

> I'm not an org-plot.el user so I cannot comment on the usefulness and
> correctness of the code, but perhaps you need to coordinate your work?

On the usefulness front, I'm quite confident that the exposes some handy
functionality. One notable result of my patches it that they allow users
to define plot types they use frequently as 1st-class types (i.e. used
just as #+PLOT: type:grid, just type:custom instead). This allows the
GNUPlot boilerplate to be dissociated from the data being plotted, which
I view as quite beneficial. This generalises the existing types into
a default set of custom types.

> That would be for after 9.4.

Of course.

Thanks for getting back to me on this,

Timothy.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: WIP: Org-plot work
  2020-09-05 15:35     ` TEC
@ 2020-09-06  5:34       ` Bastien
  2020-09-06  5:39         ` TEC
  0 siblings, 1 reply; 8+ messages in thread
From: Bastien @ 2020-09-06  5:34 UTC (permalink / raw)
  To: TEC; +Cc: org-mode-email, Eric Schulte, Mario Frasca

Hi Timothy,

TEC <tecosaur@gmail.com> writes:

> Bastien <bzg@gnu.org> writes:
>
>> Please share it on the list if you feel it's ready for a review.
>
> Well, I'm pretty sure it needs further tweaks, but I think that the bulk
> of the work would benefit from review at this point --- should I send it
> in?

Sure, please go ahead.

>> Also, Mario has been working on org-plot.el too
>
> Ah yes, well if Mario is interested I'm certainly open to such an idea :)

Great -- because I know Mario shared a lot of proposals, many of which
where probably ignored or dismissed because the patches did not follow
our conventions closely enough (despite his notable efforts).

It is of foremost importance that we stick to these conventions: they
help reduce the burden of Org maintainance.  But it is a pity that we
lose contributions because contributors cannot follow them and find it
difficult to do so.

So, be free to both cooperate on making org-plot.el more useful!

>> I'm not an org-plot.el user so I cannot comment on the usefulness and
>> correctness of the code, but perhaps you need to coordinate your work?
>
> On the usefulness front, I'm quite confident that the exposes some handy
> functionality. One notable result of my patches it that they allow users
> to define plot types they use frequently as 1st-class types (i.e. used
> just as #+PLOT: type:grid, just type:custom instead). This allows the
> GNUPlot boilerplate to be dissociated from the data being plotted, which
> I view as quite beneficial. This generalises the existing types into
> a default set of custom types.

Also, org-plot.el would do better with a maintainer - would you like
to step in?

Thanks,

-- 
 Bastien


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: WIP: Org-plot work
  2020-09-06  5:34       ` Bastien
@ 2020-09-06  5:39         ` TEC
  0 siblings, 0 replies; 8+ messages in thread
From: TEC @ 2020-09-06  5:39 UTC (permalink / raw)
  To: Bastien; +Cc: org-mode-email, Eric Schulte, Mario Frasca


Bastien <bzg@gnu.org> writes:

> Sure, please go ahead.

Will do! :)

> Great -- because I know Mario shared a lot of proposals, many of which
> where probably ignored or dismissed because the patches did not follow
> our conventions closely enough (despite his notable efforts).
>
> It is of foremost importance that we stick to these conventions: they
> help reduce the burden of Org maintainance.  But it is a pity that we
> lose contributions because contributors cannot follow them and find it
> difficult to do so.
>
> So, be free to both cooperate on making org-plot.el more useful!

Thanks. I suspect my work will need reworking to fit, but as long as
people are willing to point out what needs changing, I'm willing to take
a look at it :D

> Also, org-plot.el would do better with a maintainer - would you like
> to step in?

Simply on the basis that I'm actively interested in the functionality -
I'd be happy to sign up for this. As long as you don't mind someone a
bit green being assigned (I'm yet to use Emacs for a whole year, but I
don't see myself stopping any time soon!).

All the best,

Timothy.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: WIP: Org-plot work
@ 2020-09-07 18:54 Mario Frasca
  2020-09-08  3:21 ` TEC
  0 siblings, 1 reply; 8+ messages in thread
From: Mario Frasca @ 2020-09-07 18:54 UTC (permalink / raw)
  To: TEC, Bastien; +Cc: org-mode-email, Eric Schulte, Mario Frasca

[-- Attachment #1: Type: text/html, Size: 2046 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: WIP: Org-plot work
  2020-09-07 18:54 Mario Frasca
@ 2020-09-08  3:21 ` TEC
  0 siblings, 0 replies; 8+ messages in thread
From: TEC @ 2020-09-08  3:21 UTC (permalink / raw)
  To: Mario Frasca; +Cc: emacs-orgmode, Mario Frasca


Mario Frasca <mariotomo@inventati.org> writes:

> Hi all. Temporarily with hardly any connection. I dropped attempting
> to have my patches accepted after a couple of RFCs were met with
> silence. My understanding is that org-plot is abandoned, in favour of
> babel blocks, and I have too little interest in learning that.

Hi Mario! Good to hear from you,

I'm sorry to hear that your RFCs were met with silence - if it means
anything, had I been on the orgmode list at the time I likely would
have responded :)

I vaguely recall seeing that email saying that babel blocks should just
be used instead, and I fundamentally disagreed with the perspective of
the author. To me org-plot should be kept around, as gnuplot blocks can
not offer the same ease of functionality as org-plot. The default type
currently (pre my patches) were simple enough that they'd often be a few
lines, but org-plot has the ability to quickly create complex plots in a
concise manner which simply can't be matched by any other function in
org.

If no-one eles 'picks up the torch' with org-plot, I would like to do
so. Please give my patches a look/review, and consider bumping your RFCs
(so I have an email to reply to).

Thanks for your work,

Timothy.


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-09-08  3:22 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-08 21:36 WIP: Org-plot work TEC
2020-07-30  5:17 ` TEC
2020-09-05  7:29   ` Bastien
2020-09-05 15:35     ` TEC
2020-09-06  5:34       ` Bastien
2020-09-06  5:39         ` TEC
  -- strict thread matches above, loose matches on Subject: below --
2020-09-07 18:54 Mario Frasca
2020-09-08  3:21 ` TEC

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).