15
$\begingroup$

I'm occasionally in a situation where I have to use Mathematica on the terminal. I'd like to visualize the solutions I get from NDSolve, but when I use Plot, Mathematica just shows -Graphics- instead of trying to plot anything. I decided to write my own function for this:

AsciiPlot[functionsl_, {t_, tmin_, tmax_}] := Module[
{buffer, pts, width, height, ymin, ymax, s, functions, function, 
allpts},
width = 77; height = 24;
buffer = Table[" ", {height}, {width}];
If[Head[functionsl] === List, functions = functionsl, 
functions = {functionsl}];(*ensure functions is a list even if of length 1*)
allpts = Table[{x, (functions[[j]]) /. t -> x} // N, {j, 
 Length[functions]}, {x, tmin, tmax, (tmax - tmin)/width}];

(*Min and max of all y's across all functions to plot*)
ymin = Min[allpts[[1 ;;, 1 ;;, 2]]];
ymax = Max[allpts[[1 ;;, 1 ;;, 2]]];
s = (ymax - ymin)/(tmax - tmin);

For[i = 1, i <= Length[functions], i++,
function = functions[[i]];
pts = allpts[[i]];

(*I think it is bad form to declare a function inside a module, but it needs the variables and it is a pain to pass them all as arguments*)
set[point_, letter_] := ( 
  buffer[[height - point[[2]] + 1, point[[1]]]] = letter;);
PickLetter[slope_] := 
 Piecewise[{{"-", -.65 s < slope < .65 s}, {"/", .65 s <= slope < 
     3.5 s}, {"|", 
    3.5 s <= slope},  {"\\", -3.5 s < slope <= -.65 s}, {"|", 
    slope <= -3.5 s}}, "*"];
ScalePoint[p_] := 
 Round[{(p[[1]] - tmin)*(width - 1)/(tmax - tmin) + 
    1, (p[[2]] - ymin)*(height - 1)/(ymax - ymin) + 1}];

Map[set[ScalePoint[#], 
   PickLetter[D[function, t] /. t -> #[[1]]]] &, pts, 1];](*end for each function*)
Map[Print[StringJoin[#]] &, buffer, 1];]

How can I extend this to plot axes as well? My strategy (forcing even one function to be a list) for plotting multiple functions to mimick the native Plot[]'s behavior seems pretty unintuitive. Is there a better way?

Also, I would have preferred a function that could work on a Raster object, which would allow me also to use things like ParametricPlot and even the 3D plots with no extra effort. I couldn't think of a way to get around needing the derivative short of trying to fit curves to the rasterized image and plotting those. Any tips?

$\endgroup$
22
$\begingroup$

If you're stuck with the terminal, but have access to X11 and Java, then I suggest using JavaGraphics`, which allows you to display plots, but continue to work in the terminal. This was also answered here, but I learnt it from from Jens.

If you really want an ASCII plot, I suggest using the Terminal` package that gives you an ASCII plot:

<< Terminal`
Plot[Sinc[x], {x, 0, 20}, PlotRange -> All]

enter image description here

It also works in the front end (although, I don't know why anyone would use it in the FE):

enter image description here

$\endgroup$
  • $\begingroup$ Wow! I had no idea this existed. Unfortunately, I get Can't open display ":0.0" when I try it. I am connecting to a linux machine that is at runlevel 3 (no X11 or any graphical interface) using ssh. $\endgroup$ – 0xFE Nov 1 '12 at 3:19
  • $\begingroup$ @user141603 JavaGraphics won't work without X11, but if even Terminal (which doesn't require JavaGraphics) doesn't work for you, then I don't know... please try using only Terminal in a fresh kernel $\endgroup$ – rm -rf Nov 1 '12 at 3:24
  • $\begingroup$ I am running CentOS 6.3. I reboot, login at the "localhost login:" prompt, run "math", type "<<Terminal`" and get that error... Very odd. $\endgroup$ – 0xFE Nov 2 '12 at 3:34
  • $\begingroup$ @user141603 It doesn't work for me either... on runlevel 3 Mathematica even produces a segfault. $\endgroup$ – sebhofer Nov 2 '12 at 9:39
  • $\begingroup$ @sebhofer I've never gotten a segfault. Are you using CentOS? $\endgroup$ – 0xFE Nov 6 '12 at 2:12

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.