Compare commits

..

6 Commits

Author SHA1 Message Date
Nikolay Puzanov
3ccd9d2d22 Fix title absent 2024-08-11 23:20:44 +03:00
Nikolay Puzanov
53408f7bdf Exact numbers is not supported by gnuplot. Fix it 2024-06-06 12:48:19 +03:00
Nikolay Puzanov
1487382015 Initial add gnuplot plotting 2024-06-05 22:57:38 +03:00
Nikolay Puzanov
dfff93795e Add TODO 2023-02-20 15:16:05 +03:00
Nikolay Puzanov
ddeb6374f3 Rename string-split-str argument 2023-02-02 18:03:54 +03:00
Nikolay Puzanov
4fb8185bdc Add function for split of string by string delimiter 2023-02-02 18:00:16 +03:00
3 changed files with 131 additions and 0 deletions

View File

@@ -19,6 +19,7 @@
has-duplicates? find-duplicates has-duplicates? find-duplicates
insert-between insert-between
string-replace-text string-replace-text
string-split-str
string-split-trim string-split-trim
get-word get-word
substitute substitute
@@ -220,6 +221,18 @@
(substitute str template-format subst-list)) (substitute str template-format subst-list))
ls))) ls)))
;;; Split the string STR into a list of the substrings delimited by DELIMITER
(define (string-split-str str delimiter)
(if (string-null? str)
'()
(let ((didx (string-contains str delimiter)))
(if didx
(cons (substring str 0 didx)
(string-split-str
(substring str (+ didx (string-length delimiter)))
delimiter))
(list str)))))
;;; Split string and remove empty itemes ;;; Split string and remove empty itemes
(define (string-split-trim str pred?) (define (string-split-trim str pred?)
(remove string-null? (remove string-null?

117
embddr/gnuplot.scm Normal file
View File

@@ -0,0 +1,117 @@
(define-module (embddr gnuplot))
(import (srfi srfi-1)
(srfi srfi-26)
(ice-9 popen)
(ice-9 format))
(export make-plot-xy
plot)
;;;
;;; println
;;;
(define (>> . args)
(when (not (null? args))
(apply format (cons #t args)))
(newline))
;;;
;;; Call app and write to stdin
;;;
(define (with-output-to-spawn cmd f)
(let ((port (open-output-pipe cmd)))
(with-output-to-port port f)
(force-output port)
(close-pipe port)))
;;;
;;; Make plot
;;;
(define* (make-plot-xy #:key
(x #f) ; abscissa
y ; ordinate
(title #f)
(with "lines"))
(let ((x (or x (iota (length y)))))
(if (not (= (length x)
(length y)))
(error "Length of X and Y lists is not equal")
(lambda (key)
(case key
((x) x)
((y) y)
((title) (or title ""))
((with) with)
(else #f))))))
;;;
;;; Plot plots
;;;
(define* (plot plots
#:key
(xlabel #f)
(ylabel #f)
(title #f)
(font "Iosevka")
(font-size 11))
(let ((plots (if (list? plots) plots `(,plots))))
(if (not (apply = (map (lambda (plot) (length (plot 'x))) plots)))
(error "Length of plots is not equal")
(let* ((file-port (mkstemp "/tmp/plot-data-XXXXXX" "w"))
(file-name (port-filename file-port)))
;; Write data to temporary file
(with-output-to-port file-port
(lambda ()
(for-each
(cut >> <>)
(map (lambda (sample) (string-join (map
(lambda (x) (number->string
(exact->inexact x)))
sample) " "))
(apply zip (cons ((first plots) 'x)
(map (lambda (plot) (plot 'y)) plots)))))))
(close-port file-port)
;; Call gnuplot
(with-output-to-spawn
"gnuplot"
(lambda ()
(>> "set term x11 enhanced font '~a,~a' persist size 640,480" font font-size)
;; (>> "set output '~a'" "draw.png")
(>> "set grid")
(when xlabel (>> "set xlabel '~a'" xlabel))
(when ylabel (>> "set ylabel '~a'" ylabel))
(when title (>> "set title '~a'" title))
(>> "plot ~a"
(string-join
(map (lambda (plot n)
(format #f "'~a' using 1:~a with ~a~a"
file-name
n
(plot 'with)
(if (plot 'title)
(format #f " title '~a'" (plot 'title))
"")))
plots
(iota (length plots) 2))
",\\\n"))))
;; Delete temporary file
(delete-file file-name)))))
;; (define (main args)
;; (plot
;; `(,(make-plot-xy
;; #:x (iota 17 20 -1)
;; #:y '(1 2 3 4 3 2 1 0 -1 -2 -3 -4 -3 -2 -1 0 1)
;; #:title "plot A"
;; #:with "lines lw 2")
;; ,(make-plot-xy
;; #:x (iota 17 20 -1)
;; #:y (map (cut * -0.5 <>) '(1 2 3 4 3 2 1 0 -1 -2 -3 -4 -3 -2 -1 0 1))
;; #:title "plot B"
;; #:with "lines"))))

View File

@@ -139,6 +139,7 @@
((string-ci= name "$timescale") ((string-ci= name "$timescale")
(next-cmd (parse-timescale (second cmd)) scope tags+signals)) (next-cmd (parse-timescale (second cmd)) scope tags+signals))
;; TODO: Add scope type (make scope as pair '(scope-type . scope-name))
((string-ci= name "$scope") ((string-ci= name "$scope")
(next-cmd timescale (cons (third cmd) scope) tags+signals)) (next-cmd timescale (cons (third cmd) scope) tags+signals))