From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dan Davison Subject: Re: graphing from org-tables Date: Sat, 26 Jul 2008 19:15:24 +0100 Message-ID: <20080726181524.GA10786@stats.ox.ac.uk> References: <4889f6f8.29578c0a.3e24.ffff8395@mx.google.com> <20080725162527.GA54528@yog-sothoth.mohorovi.cc> <488a2450.1e078e0a.2bc0.181f@mx.google.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Return-path: Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KMoIl-0007VO-5Z for emacs-orgmode@gnu.org; Sat, 26 Jul 2008 14:15:31 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KMoIk-0007Ta-5Q for emacs-orgmode@gnu.org; Sat, 26 Jul 2008 14:15:30 -0400 Received: from [199.232.76.173] (port=39877 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KMoIj-0007T9-Ow for emacs-orgmode@gnu.org; Sat, 26 Jul 2008 14:15:29 -0400 Received: from markov.stats.ox.ac.uk ([163.1.210.1]:36469) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KMoIj-0000VN-B7 for emacs-orgmode@gnu.org; Sat, 26 Jul 2008 14:15:29 -0400 Content-Disposition: inline In-Reply-To: <488a2450.1e078e0a.2bc0.181f@mx.google.com> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Eric Schulte Cc: Org-mode R (www.r-project.org) is pretty good for data plotting and statistical analyses. Here's my effort at the org-table-plot function, using R. Since R contains a csv importer that can read from stdin, it's pretty simple. I've tried to code it so that you can provide an arbitrary R function as the optional argument, so in principle you can do to your org-table anything that R is capable of in the realms of data analysis and visualisation. (defun org-table-R-plot (&optional R-function) "Plot the current table using R. The table is transformed into a dataframe in R. Optional argument R-function is a string which is either the name of an R function, or an anonymous function definition of the form (function(d) {...}), requiring a single argument (the dataframe). The default is to use the R function 'plot' which produces scatter plots of all pairwise combinations of columns. An example custom plotting function is: * plot column 3 against column 1, adding least-squares linear regression fit in blue (function(df) { plot(x=df[,1], y=df[,3]) ; abline(lm(df[,3] ~ df[,1]), col=\"blue\") }) " (interactive) (unless R-function (set 'R-function "plot")) (let ((file (make-temp-file "org-table-R-plot"))) (org-table-export file "orgtbl-to-csv") (set-buffer (find-file-noselect file)) (shell-command-on-region (point-min) (point-max) (concat "Rscript -e 'X11() ; " R-function "(read.csv(\"stdin\")) ; system(\"sleep 60\")'")) (delete-file file))) R is at www.r-project.org (package r-base on ubuntu/debian) Rscript is a command line non-interactive scripting utility that is bundled automatically with the R installation. I reckon it'll be OK on OSX but no idea about Windows. My function doesn't have to be used for plotting; the R-function argument can be any function operating on the data from the org-table, producing numerical or graphical output. There's several things that need to be sorted out with my function, e.g. (i) I haven't worked out how to return control to the emacs process while keeping the plot window there. I tried adding an & to the shell-command, but that seemed to result in R receiving nothing on stdin. So I've got that 'sleep 60' hack in there currently; use C-g if you get bored of your plot. (ii) If the R-function isn't doing graphics, then the call to X11() gets in the way. X11() would only work on linux/mac OSX(?) anyway. (iii) I'm afraid I don't even know yet how to pass the optional string argument using M-x org-table-R-plot. Is it possible with some sort of prefix argument, and an (interactive something) declaration? Anyway, it seems to work if you evaluate e.g. (org-table-R-plot "(function(df) { plot(x=df[,1], y=df[,3]) ; abline(lm(df[,3] ~ df[,1]), col=\"blue\") })") Suggestions for improvements welcome! Dan On Fri, Jul 25, 2008 at 12:07:00PM -0700, Eric Schulte wrote: > > I had some time waiting for things to execute, so I condensed your > process into a single command (borrowing heavily from > org-export-table). > > (defun org-table/gnuplot (&optional x-col) > "Plot the current table using gnuplot. Use a prefix argument > to specify a column to use for the x-coordinates, to use the row > number for the x-coordinates provide a prefix argument of 0." > (interactive "p") > (message (format "%S" x-col)) > (unless (org-at-table-p) > (error "No table at point")) > (require 'org-exp) > (require 'gnuplot) > (org-table-align) ;; make sure we have everything we need > (let* ((beg (org-table-begin)) > (end (org-table-end)) > (cols (save-excursion > (goto-char end) > (backward-char 3) > (org-table-current-column))) > (data-beg (if (and > (goto-char beg) > (re-search-forward org-table-dataline-regexp end t) > (re-search-forward org-table-hline-regexp end t) > (re-search-forward org-table-dataline-regexp end t)) > (match-beginning 0) > beg)) > (skip (- (line-number-at-pos data-beg) (line-number-at-pos beg))) > (exp-format (format "orgtbl-to-tsv :skip %d" skip)) > (file (make-temp-file "org-table-plot"))) > ;; export table > (org-table-export file exp-format) > (with-temp-buffer > ;; write script > (insert (org-table/gnuplot-script file x-col cols)) > ;; graph table > (gnuplot-mode) > (gnuplot-send-buffer-to-gnuplot) > (bury-buffer (get-buffer "*gnuplot*"))) > (delete-file file))) > > (defun org-table/gnuplot-script (file x-col num-cols) > (let ((plot-str "'%s' using %s:%d with lines title '%d'");; "\\\n ," > script) > (dotimes (col (+ 1 num-cols)) > (unless (or (and x-col (equal col x-col)) (equal col 0)) > (setf script (cons (format plot-str file (or (and x-col (format "%d" x-col)) "") col col) script)))) > (concat "plot " (mapconcat 'identity (reverse script) "\\\n ,")))) > > On Friday, July 25, at 17:25, James TD Smith wrote: > > On 2008-07-25 08:53:31(-0700), Eric Schulte wrote: > > > > > > Any advice for quick graphing of a table in org-mode? > > > > > > > I have a setup for plotting data from tables. I'm not sure if it's exactly what > > you want, but yoy may find it useful. > > > > 1. Add the following to your .emacs: > > > > (defun ahkt-plot-table (script) > > "util function to export and plot a table using the supplied > > gnuplot `script'" > > (org-table-export) > > (let ((cbuf (current-buffer)) > > (cwin (selected-window))) > > (save-restriction > > (save-excursion > > (find-file script) > > (gnuplot-send-buffer-to-gnuplot) > > (bury-buffer) > > (bury-buffer (get-buffer "*gnuplot*")))) > > (and (window-live-p cwin) (select-window cwin)) > > (switch-to-buffer cbuf) > > (delete-other-windows))) > > > > 2. Create a gnuplot script which plots data from a file. > > > > 3. Add the following properties to the headline containing the table. > > TABLE_EXPORT_FILE > > TABLE_EXPORT_FORMAT orgtbl-to-generic :skip 4 :splice t :sep "\t" > > > > 4. Add an org link in the table (it must be in the table otherwise the export > > doesn't work) as below: > > [[elisp:(ahkt-plot-table "")][plot table]] > > > > I suggest you put it at the top of the table. > > You will then need to adjust the 'skip' parameter in the export format depending > > on the number of lines at the top of the table which should not be exported > > (hlines, more than one plotting link etc). > > > > 5. You should then be able to open the link, and get a plot of the table > > contents. > > > > > > -- > > |---| > > > > > > _______________________________________________ > > Emacs-orgmode mailing list > > Remember: use `Reply All' to send replies to the list. > > Emacs-orgmode@gnu.org > > http://lists.gnu.org/mailman/listinfo/emacs-orgmode > > -- > schulte > > > _______________________________________________ > Emacs-orgmode mailing list > Remember: use `Reply All' to send replies to the list. > Emacs-orgmode@gnu.org > http://lists.gnu.org/mailman/listinfo/emacs-orgmode