7

Say i have a mathematical function f I want to plot.

The easiest way to plot this is to evaluate it at small steps along the plotting domain and generate the points.

e.g f(0); f(0.1); f(0.2) ... get converted into (0, f(0)); (0.1, f(0.1)); (0.2, f(0.2)) ...

If one wants to draw a curve rather than dots, one could do

draw (0, f(0))--(0.1, f(0.1)); 
draw (0.1, f(0.1))--(0.2, f(0.2));

Inside of a loop. In other words, you write a loop, store the result of the prvious computation, compute the current value of x, draw a straigth segment, update x and continue.

Is it possible to do, for example:

%psuedocode
pair list[];
draw list;

?

3
  • 1
    Yes, this is what \draw plot coordinates {<list>}; in TikZ does. – user194703 Dec 24 '19 at 3:00
  • That's for tikz, does that work in metapost too? – Makogan Dec 24 '19 at 3:02
  • I think so but I did not use it in a long while. – user194703 Dec 24 '19 at 3:05
10

Here's one possibility with metapost. For a macro to take an array as an argument, it is declared as a suffix argument, i.e. one that has suffixes which in this case are 0,1,2,.... The input array must start with index/suffix 0.

\documentclass[border=10cm]{standalone}
\usepackage{luamplib}

\begin{document}
\begin{mplibcode}
vardef pairs(suffix P)=
    save p_,i_; path p_;
    i_:=0;
    p_:=P[0] forever: exitif not (known P[incr i_]); --P[i_] endfor;
    p_
enddef;

beginfig(0);
u:=1cm;
pair p[];
p[0]=origin;
p[1]=u*(1,1);
p[2]=u*(2,0);
p[3]=u*(4,0);

draw pairs(p) withpen pencircle scaled 1bp withcolor red;
endfig;
\end{mplibcode}

\end{document}

enter image description here

Edit: As per Thruston's suggestion, we can be a bit more general here. If you would like the option of straight segments or Bezier curves then you could use:

\begin{mplibcode}
vardef pairs(suffix P)(text joiner)=
    save p_,i_; path p_;
    i_:=0;
    P[0] forever: exitif not (known P[incr i_]); joiner P[i_] endfor
enddef;

beginfig(0);
u:=1cm;
pair p[];
p[0]=origin;
p[1]=u*(1,1);
p[2]=u*(2,0);
p[3]=u*(4,-1);
drawoptions(withpen pencircle scaled 1bp);
draw pairs(p,..) withcolor red;
draw pairs(p,--) withcolor blue;
draw pairs(p,{right}..{right});
%k:=0;
%draw pairs(p,{dir (incr k*30)}..{right}) withcolor green;
drawoptions();

endfig;
\end{mplibcode}

enter image description here

2
  • 1
    You could make the pairs macro more generic if you defined it as vardef pairs(suffix P)(text joiner) = ... and then passed .. or -- or what you like as the second argument. – Thruston Feb 23 '20 at 13:38
  • @Thruston That's a good idea..I both didn't think of that and didn't realize (or forgot) that I can delimit a text parameter and keep the ability to pass additional stuff. – Scott H. Feb 24 '20 at 5:18
6

Since many TikZ answers get MetaPost answers (which is of course great) here is a TikZ answer for this presumably MetaPost question. Given a list, say, \def\mylist{(0,1) (1,2) (2.5,1/2)} it is very well known that you can plot this list with \draw[blue] plot[smooth] coordinates {\mylist};. What is somewhat less known is that you can also plot lists which have the Mathematica/C++ array structure, say, \def\mylist{{0,1},{1,2},{2.5,1/2}}. This works by exploiting that TikZ can parse and access arrays,

\draw plot[samples at={0,1,2}] ({{\mylist}[\x][0]},{{\mylist}[\x][1]});

Full MWE with smooth examples:

\documentclass[tikz,margin=3]{standalone}
\begin{document}
\begin{tikzpicture}
\def\mylist{(0,1) (1,2) (2.5,1/2)}
\draw plot coordinates {\mylist};
\draw[blue] plot[smooth] coordinates {\mylist};
\begin{scope}[yshift=-4cm]
\def\mylist{{0,1},{1,2},{2.5,1/2}}
\draw plot[samples at={0,1,2}] ({{\mylist}[\x][0]},{{\mylist}[\x][1]});
\draw[blue] plot[smooth,samples at={0,1,2}] ({{\mylist}[\x][0]},{{\mylist}[\x][1]});
\end{scope}
\end{tikzpicture}
\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.