Can MetaPost draw directly datapoints from a data file?
When I need to draw datapoints from a external data file I’m using lua, like this: \starttext \startluacode Elemento = {} x = {} y ={} z= {} carga = {} i=1 context("\\startMPcode”) context("numeric u; u := 1.5cm;") for line in io.lines("molecule.xyz") do local a, b, c, d, e = string.match(line, '(%a+)%s*%s*(%S+)%s*%s*(%S+)%s*%s*(%S+)%s*%s*(%S+)') Elemento[i]= a x[i]= tonumber(b) y[i]= tonumber(c) z[i]= tonumber(d) carga[i]= tonumber(e) context("label(\"%s\", (%0.6f u, %0.6f u));", a, x[i],y[i]) i=i+1 end context("\\stopMPcode”) \stopluacode \stoptext Is there a way to pass directly the external data to MetaPost without using Lua? I know that I can use a similar function to gdata from graph.mp. I try to reuse this piece of code, but not works. \startMPcode vardef Grdln_@#(expr f) = save n_, s_; string s_; s_ = readfrom f; string @#[]; if s_<>EOF: @#1 := loptok s_; n_ = if @#1="%": 0 else: 1 fi; forever: @#[incr n_] := loptok s_; exitif @#[n_]=" "; endfor @#1<>" " else: false fi enddef; Grdln_$("molecule.xyz"); \stopMPcode Jorge
On 12/28/2017 6:36 PM, Jorge Manuel wrote:
When I need to draw datapoints from a external data file I’m using lua, like this:
\starttext
\startluacode
Elemento = {} x = {} y ={} z= {} carga = {} i=1 context("\\startMPcode”)
context("numeric u; u := 1.5cm;") for line in io.lines("molecule.xyz http://molecule.xyz") do local a, b, c, d, e = string.match(line, '(%a+)%s*%s*(%S+)%s*%s*(%S+)%s*%s*(%S+)%s*%s*(%S+)') Elemento[i]= a x[i]= tonumber(b) y[i]= tonumber(c) z[i]= tonumber(d) carga[i]= tonumber(e)
context("label(\"%s\", (%0.6f u, %0.6f u));", a, x[i],y[i])
i=i+1 end
context("\\stopMPcode”)
\stopluacode
\stoptext
*Is there a way to pass directly the external data to MetaPost without using Lua?*
I know that I can use a similar function to gdata from graph.mp. I try to reuse this piece of code, but not works.
\startMPcode
vardef Grdln_@#(expr f) = save n_, s_; string s_; s_ = readfrom f; string @#[]; if s_<>EOF: @#1 := loptok s_; n_ = if @#1="%": 0 else: 1 fi; forever: @#[incr n_] := loptok s_; exitif @#[n_]=" "; endfor @#1<>" " else: false fi enddef;
Grdln_$("molecule.xyz http://molecule.xyz");
\stopMPcode mp file handling is rather crippled so this is where lua is better
\starttext \startluacode MP.mycode = { } local elements = { } function MP.mycode.loadelements(filename) elements = { } for line in io.lines(filename) do elements[#elements+1] = { string.match(line, '(%S+)%s*(%S+)%s*(%S+)%s*(%S+)%s*(%S+)') } end end function MP.mycode.nofelements() mp.print(#elements) end function MP.mycode.getlabel(i) mp.quoted(elements[i][1]) end function MP.mycode.getoffset(i) mp.pair(elements[i][2],elements[i][3]) end \stopluacode \startMPcode lua.MP.mycode.loadelements("molecule.xyz") ; for i=1 upto lua.MP.mycode.nofelements() : label (lua.MP.mycode.getlabel(i),50 * lua.MP.mycode.getoffset(i)) ; endfor ; \stopMPcode \startMPcode def my_loadelements(expr name) = lua.MP.mycode.loadelements(name) ; enddef ; vardef my_nofelements = lua.MP.mycode.nofelements() enddef ; vardef my_label(expr i) = lua.MP.mycode.getlabel(i) enddef ; vardef my_offset(expr i) = lua.MP.mycode.getoffset(i) enddef ; my_loadelements("molecule.xyz") ; for i=1 upto my_nofelements : label (my_label(i),50 * my_offset(i)) ; endfor ; \stopMPcode \stoptext If you use that kind of code a lot you can hide the lua calls in macros which makes it look like metapost does it all. Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
Thanks a lot for this nice and clean solution. It’s fantastic. Now it is very easy to make scatter plots from the output of c++ libraries and other kind of applications: two axes and a path build like this path curve; numeric i; i:=1; curve := my_offset(i) forever: hide(i := i + 1) exitif i > my_nofelements .. my_offset(i) endfor; Thanks again Have a great 2018 Jorge
No dia 28/12/2017, às 18:47, Hans Hagen
escreveu: \starttext
\startluacode MP.mycode = { }
local elements = { }
function MP.mycode.loadelements(filename) elements = { } for line in io.lines(filename) do elements[#elements+1] = { string.match(line, '(%S+)%s*(%S+)%s*(%S+)%s*(%S+)%s*(%S+)') } end end
function MP.mycode.nofelements() mp.print(#elements) end
function MP.mycode.getlabel(i) mp.quoted(elements[i][1]) end
function MP.mycode.getoffset(i) mp.pair(elements[i][2],elements[i][3]) end \stopluacode
\startMPcode lua.MP.mycode.loadelements("molecule.xyz http://molecule.xyz/") ; for i=1 upto lua.MP.mycode.nofelements() : label (lua.MP.mycode.getlabel(i),50 * lua.MP.mycode.getoffset(i)) ; endfor ; \stopMPcode
\startMPcode def my_loadelements(expr name) = lua.MP.mycode.loadelements(name) ; enddef ; vardef my_nofelements = lua.MP.mycode.nofelements() enddef ; vardef my_label(expr i) = lua.MP.mycode.getlabel(i) enddef ; vardef my_offset(expr i) = lua.MP.mycode.getoffset(i) enddef ;
my_loadelements("molecule.xyz http://molecule.xyz/") ; for i=1 upto my_nofelements : label (my_label(i),50 * my_offset(i)) ; endfor ; \stopMPcode
\stoptext
participants (2)
-
Hans Hagen
-
Jorge Manuel