Repository navigation
add set terminal svg and capture output to svg buffer #20
Description
Activity
It might be possible to implement this as a more general feature: Emacs could capture Gnuplot's output in any image format by using temporary files, and place it in a buffer. This would effectively allow you to plot into an Emacs window, and you could use
image-modeto toggle between SVG source and rendered image.In fact, this is already mostly implemented by the
gnuplot-modecode that inserts inline images into the Gnuplot comint buffer. It would mostly be a matter of inserting images into a different buffer, and enabling different image types besides "png".The lack of a closing
</svg>tag looks to me like a buffering problem, FWIW. If you doset output "blah", plot something, and thenset output, the file is flushed and the closing tag appears.thanks for the reply! this quite simplifies the workflow using
gnuplot-mode.set terminal svg set title 'salinity' set ylabel "mS/cm" set xlabel "m³/d" set output "/tmp/b.svg" plot '/tmp/org-plot18589dFU' using 6:3 with points title '' set outputbut I've never really programmed in elisp, so I'm a bit lost in your code, looking for what to change/add in order to automatize the process.
I guess I would like to do this:
when one sets the terminal mode to an image type, the output is diverted to its corresponding image buffer (unless explicitly diverted to a file). what happens now is that it goes to the gnuplot "comint" buffer.so I would execute
set terminal pngand gnuplot-mode sees this and sets the output to the buffer*gnuplot-png*.
same forset terminal svgsending the svg code to the*gnuplot-svg*buffer.is this viable? what keywords to look for in the code?
I think this is viable. I have a branch with a proof-of-concept implementation which I will push shortly for you to try out, if you like. I am still working on getting the buffering issue sorted out.
I had thought of having a single
*gnuplot output*buffer, but your suggestion is possible too. Is it useful to have separate buffers for separate image types?Please try out the prototype implementation of this in
plot-to-windowbranch. In a fresh Emacs, load "gnuplot.el" from that branch, then do the following:M-x gnuplot-show-gnuplot-buffer- From the "Gnuplot" menu, choose "Display plot output > In dedicated buffer" and "Display plot output > SVG images"
- Plot something as normal
- You should get a new pop-up buffer called
*gnuplot output*containing the generated SVG file. In my Emacs (without SVG support) it is innxml-mode. If you have SVG support, it might show up as an image, in which case you could useC-c C-cto toggle between viewing the source and rendered.
Note: I've never used
org-plotso I don't know how this feature should interact with it. If we can first get this working when plotting from the Gnuplot interaction buffer and gnuplot-mode buffers, that can be tackled separately.with the current changes I can indeed get the graph in a svg buffer.
how can I visualize/log what
org-plotdoes withgnuplot-mode?
with the present changes, org-plot does not manage to generate output consistently.if I run
org-plot/gnuplot, the possible outcomes are:- it just works (in particular if I run it as first thing).
- it uses gnuplot-send-hiding-output to report "Selecting deleted buffer" (nothing else happens)
- it hides the output buffer, says 'Buffer "gnuplot" has a running process; kill it?' (and then it works, showing again the output buffer or it hangs, with the spinning mouse until C-g)
Hmm, that is strange. It may help to do
M-x toggle-debug-on-error, which should give you a backtrace on errors which you could copy and paste here. However, this does not tend to work very well for filter functions, which run asynchronously.Could you post a minimal
org-modeexample as a Gist, plus a recipe to use for testing?me behind very intermittent internet connection. was not logged in when I created this:
https://gist.github.com/anonymous/697852a0ab35a15f208c
updated
https://gist.github.com/mfrasca/330b268fa62b390ec2dcis there a different way to reset gnuplot?
(when (get-buffer "*gnuplot*") ;; reset *gnuplot* if it already running (with-current-buffer "*gnuplot*" (goto-char (point-max)) (gnuplot-delchar-or-maybe-eof nil)))this asks for user intervention.
I'm looking at the code of
org-plot/gnuplot... one point I notice is that it tries to do some cleanup relying on an idle timer. the cleanup doesn't happen. do you think it could be possible for gnuplot-mode to offer callbacks, that could be called after specific events in gnuplot-mode?is it OK to invoke
gnuplot-send-buffer-to-gnuplotat the end of awith-temp-bufferblock?-
Thanks for the Gist recipe. I have pretty limited time this week, but I will try to look into this.
-
There is something funny going on with handling the gnuplot buffer and process.
-
Yes, it should be OK to have
gnuplot-send-buffer-to-gnuplotwithinwithin-temp-buffer. -
Adding more hooks is a good possibility, but there is another problem. I don't see how the line
(run-with-idle-timer 0.1 nil (lambda () (delete-file data-file)))in
org-plotcan work without lexical-binding. The binding fordata-fileis long gone by the time the idle timer runs. It should probably be:(run-with-idle-timer 0.1 nil #'delete-file data-file)-
Once i made that change to org-plot, I seem to be able to plot your table repeatedly using
C-c " gwithout problems. Does that also work for you?Hmm, no, it's still possible to get the "Selecting deleted buffer" error. Investigating..
I suspect the buffer being deleted is
*gnuplot*(if I have a window visit it, invokeorg-plot/gnuplot, the window will switch to a different buffer)I pushed a small commit to the
plot-to-windowbranch which tweaks gnuplot's process handling slightly, and seems to improve things. However, I think how it works with the process needs to be improved more generally, and I don't have the time right now. In particular, it seems bad to have bothgnuplot-bufferand agnuplot-processvariables, since they can get out of sync. Instead, we should keep track of the buffer and use(get-buffer-process gnuplot-buffer).lisp doubt: how about this as a callback...
(run-with-idle-timer 0.1 nil (list #'delete-file data-file))
No, look at the docstring for
run-with-idle-timer. The third argument has to be a function, and then any remaining arguments will be saved and passed to that function when it is called. The version I posted works.If you can reproduce the "Selecting deleted buffer" error, could you please do
M-x toggle-debug-on-errorand paste the backtrace it produces?You're right, it is probably the
*gnuplot*buffer being deleted. I guessgnuplot-send-hiding-outputshould handle this case more carefully … I have to think about this.I can consistently reproduce the "Selecting deleted buffer" error (every second time I run
org-plot/gnuplot), but the program does not crash, so no backtrace. or am I missing something?more info: in my /tmp dir, I have these files:
-rw------- 1 mario mario 1306 Nov 1 18:54 org-plot20401v0t
-rw------- 1 mario mario 1306 Nov 1 18:54 org-plot204018-z
-rw------- 1 mario mario 0 Nov 1 18:54 gnuplot20401uID
-rw------- 1 mario mario 1306 Nov 1 18:54 org-plot204017SJ
-rw------- 1 mario mario 1306 Nov 1 18:54 org-plot20401IdP
-rw------- 1 mario mario 0 Nov 1 18:54 gnuplot20401VnV
-rw------- 1 mario mario 1306 Nov 1 18:54 org-plot20401ixb
-rw------- 1 mario mario 1306 Nov 1 18:54 org-plot20401v7h
-rw------- 1 mario mario 0 Nov 1 18:54 gnuplot204018Fo
-rw------- 1 mario mario 1306 Nov 1 18:54 org-plot20401JQu
-rw------- 1 mario mario 1306 Nov 1 18:54 org-plot20401Wa0
-rw------- 1 mario mario 0 Nov 1 18:54 gnuplot20401VuJ
-rw------- 1 mario mario 9186 Nov 1 18:54 gnuplot20401IkDfiles seem to be generated in pairs, subsequent orgplot* files are equal. when the operation is successful, gnuplot* files are also generated in pairs, otherwise only the first, empty one, is generated.
What does Emacs print if you type
M-: debug-on-error RET? If it isnil, please typeM-x toggle-debug-on-errorand then try to reproduce theSelecting deleted buffererror. Does that display a Lisp backtrace (in a*Backtrace*buffer)? If not, then the error is happening in some asynchronous process-filter function , and will be harder to debug.Please try the latest revision on the
plot-to-windowbranch. I think it fixes this bug.I still sometimes see zombie gnuplot processes hanging around, but I'm not sure why.
You should also apply this patch to
org-plot: https://gist.github.com/joddie/afa03f5c53d61da1b26a . If you'd like to report it as a bug to the org-mode maintainers, even better :)I do think
org-plotcould ensure it starts with a fresh gnuplot process more cleanly than by doing(gnuplot-delchar-or-eof)-- probably it would be better to do(delete-process gnuplot-process)or similar, but I'm not sure.in
*scratch*:debug-on-error <C-j> twith your edits and if I kill the gnuplot process before invoking
org-plot/gnuplot, then I can consistently successfully runorg-plot/gnuplot. :)seems indeed that the way org-plot tries to get a fresh gnuplot process doesn't work properly.
but why should we actually need a fresh process. isn'tresetgood enough?
if I just remove the(gnuplot-delchar-or-maybe-eof nil)it works just as well, and without me needing to kill the process by hand.
there's still two gnuplot (not any more the org-plot) temporary files hanging in the
/tmpdir.gnuplot-modeuses temporary files to get image output fromgnuplot, so it's expected you should see some temporary files hanging around. I suppose it might be better to explicitly clean them up in a similar way to whatorg-plotdoes.Do you have to kill the gnuplot process every time before running
org-plot/gnuplot? That does seem strange; I don't see that behavior here. If you're interested in debugging further, I recommend Edebug. Go to the definition of the function you are interested in (e.g.org-plot/gnuplot) and hitC-u C-M-x. Next time it is called you can step through with the space bar, evaluate variables withe, etc. There are some good Edebug tutorials around on the web and I think it's documented in the ELisp manual as well.Otherwise i don't have too many more ideas what problem you might be seeing right now ...
I will try debugging, but what do you think about not killing the process and rely on
reset?
it works fine here.- locked and limited conversation to collaborators
on May 28, 2025
I guess this is the first place where intervention is needed:
I'm holding a spreadsheet in an emacs buffer, not yet decided whether to use
sesororg., in both cases I have to go throughgnuplotand in particular org-plot makes use ofgnuplot-mode.I'd like to grab the graph in a buffer, in svg format.
the svg format allows me further editing of the graph still using emacs.
my workflows using ses:
*gnuplot trail*bufferthe workflow using org-plot is more complicated:
*gnuplot*buffer and copy the commandsgnuplot-make-bufferto open a new gnuplot bufferset terminal svg*gnuplot*bufferI do not see svg in the possible terminals offered by gnuplot-mode.
when terminal is set to svg, I would expect gnuplot-mode to do this:
first time gnuplot outputs svg code, it will be almost complete (misses the closing svg tag).
subsequent times it starts immediately after the closing defs tag.