# Plots and graphics in STACK questions.

Plots and graphics can be placed into any of the CASText fields.

The main way to create plots with the core STACK commands is using Maxima. As of version 4.0, the tags `{#...#}`

provide the possibility to interact with 3rd party scripts. If you have examples of this, please contact the developers. This page is about core supported functionality.

## plot()

In STACK, the `plot`

command has been defined to be a wrapper for Maxima's `plot2d`

command. The wrapper makes sure that an image file is given an appropriate name, file location, and that Maxima returns a URL to the user giving the image. Not all of the features of `plot2d`

are available through `plot`

.

Try, for example, the following in the question stem.

```
{@plot(x^2,[x,-1,1])@}
```

You can add a second variable to control the axes.

```
plot(x^2,[x,-1,1],[y,0,2])
```

However, Maxima will not always allow you to get the axes you want (this is a bug in Maxima). To get many plots in one window, we need to define a list of expressions.

```
plot([x^2,sin(x)],[x,-1,1])
```

This can be done with Maxima's `makelist`

command

```
(p(k):=x^k,pl:makelist(p(k),k,1,5),plot(pl,[x,-1,1]))
```

Notes:

- Currently STACK has
`gnuplot`

return a basic SVG image. - Only a very few of Maxima's
`plot_options`

are respected by`plot`

, mainly for security reasons. (`plot`

calls an external command`gnuplot`

which writes to the server filesystem.) - The
`draw`

package is currently not supported. - To change the size of the image use the Maxima variable
`size`

, e.g.`plot(x^2,[x,-1,1],[size,250,250])`

. - By default plots are surrounded by the
`<div class="stack_plot">`

. This puts whitespace around a plot, and places the plot in the centre of the screen. To suppress this`div`

use the option`[plottags,false]`

.

## Traditional axes

Note: this example only works with newer versions of Maxima (and not before 5.31.3).

A traditional plot with the axes in the middle can be generated by the following.

```
{@plot([x^2/(1+x^2),2*x/(1+x^2)^2], [x, -2, 2], [y,-2.1,2.1], [box, false], [yx_ratio, 1], [axes, solid], [xtics, -2, 0.5, 2],[ytics, -2, 0.5, 2])@}
```

## Labels

The `ylabel`

command rotates its argument through 90 degrees. If you want a horizontal label on the -axis you will need to use the `label`

command instead.

```
{@plot([x^2/(1+x^2),2*x/(1+x^2)^2], [x, -2, 2], [y,-2.1,2.1], [label,["y",-2.5,0.25]])@}
```

## Grid

The grid is controlled by the maxima command `grid2d`

(newer versions of Maxima only). Compare the following.

```
{@plot([x^2/(1+x^2),2*x/(1+x^2)^2], [x, -2, 2], [y,-2.1,2.1], grid2d)@}
{@plot([x^2/(1+x^2),2*x/(1+x^2)^2], [x, -2, 2], [y,-2.1,2.1])@}
```

## Options

The following `plot`

options are currently supported by STACK. If you would like to expand the range of options available please contact the developers.

```
[xlabel, ylabel, label, legend, color, style, point_type, nticks, logx, logy, axes, box, plot_realpart, yx_ratio, xtics, ytics, ztic, grid2d],
```

Please see Maxima's documentation for more information on these options. Note that the `draw`

package is currently not supported.

Notes on some of the options.

- The default in Maxima is to include a legend consisting of a
`string`

representation of the plot. In STACK this is turned off by default. To switch it back on, use the command`[legend, true]`

. Any other value of the option`legend`

will respect the original command.

## Alternate text for an image (alt tag)

The default alternate text for an image (img alt tag) generated by a plot command such as

```
plot(x^2,[x,-2,2]);
```

is "STACK auto-generated plot of x^2 with parameters [[x,-2,2]]". If your question asks students to "give an algebraic expression which describes this curve" then you will need to set alternative text which does not include the answer.

To set a specific alt tag, pass an equation `[alt,"..."]`

as an argument to the plot function.

```
plot(x^2,[x,-2,2],[alt,"Hello world"]);
```

If you would like an expression as part of this then try

```
p:sin(x);
plot(p,[x,-2,2],[alt,sconcat("Here is ",string(p))]);
```

## Language strings

Note, you cannot put language strings directly into the alt-text. E.g. the following will not be translated.

```
{@plot(x^2,[x,-2,2],[alt,"[[lang code='en,other']]A quadratic curve[[/lang]][[lang code='no']]En kvadratisk kurve[[/lang]]"])@}
```

You can define a castext element in the question variables which does get translated, e.g.

```
altlbls: castext("[[lang code='en,other']]A quadratic curve[[/lang]][[lang code='no']]En kvadratisk kurve[[/lang]]");
```

and then use this in the castext:

```
{@plot(x^2,[x,-2,2],[alt,altlbls])@}
```

This technique can be put into other language dependent plot variables. E.g.

```
xlabeltrans: castext("[[lang code='en,other']]Independent variable[[/lang]][[lang code='no']]Uavhengig variabel[[/lang]]");
ylabeltrans: castext("[[lang code='en,other']]Dependent variable[[/lang]][[lang code='no']]Avhengig variabel[[/lang]]");
```

Then in the castext `{@plot(x*sin(1/x),[x,-1,2],[xlabel,xlabeltrans],[ylabel,ylabeltrans])@}`

## A catalogue of plots

The following CASText gives representative examples of the plot2d features supported by STACK's plot command. Cut and paste it into the CASchat script. Beware that these are likely to cause a timeout on the CAS if you try them all at once.

```
<h3>Basic plot</h3>
{@plot(x^2,[x,-2,2])@}
The following plot tests the option to explicitly test the alt-text.
{@plot(x^3,[x,-3,3], [alt,"What is this function?"])@}
<h3>Multiple graphs, clips the \(y\) values</h3>
{@plot([x^3,exp(x)],[x,-2,2],[y,-4,4])@}
<h3>With and without a grid</h3>
{@plot([x^2/(1+x^2),2*x/(1+x^2)^2], [x, -2, 2], [y,-2.1,2.1], grid2d)@}
{@plot([x^2/(1+x^2),2*x/(1+x^2)^2], [x, -2, 2], [y,-2.1,2.1])@}
<h3>Discrete plots</h3>
Basic discrete plot.
{@plot([discrete,[[0,0],[1,1],[0,2]]])@}
Points: by default the points are too large!
{@plot([discrete,[[0,0], [1,1], [1.5,(1.5)^2]]],[x,-2,2],[style, [points]],[point_type, bullet])@}
{@plot([discrete,[[0,0], [1,1], [1.5,(1.5)^2]]],[x,-2,2],[style, [points, 1]],[point_type, bullet])@}
Notice the size of the points is controlled by the second argument in the list `[points, 1]`. This is documented in Maxima under "Plot option: style". A more complicated example is below.
{@plot([[discrete,[[0,0], [1,1], [1.5,(1.5)^2]]],[discrete,[[0,0.1], [0.75,1], [1.25,1.5]]]],[style, [points, 1, red, 1 ], [points, 1.5, blue, 1]])@}
Combination of discrete plots with normal plots.
{@plot([x^2, [discrete,[ [0,0], [1,1], [0,2]]]],[x,-2,2])@}
{@plot([x^2, [discrete,[ [0,0], [1,1], [1.5,(1.5)^2]]]],[x,-2,2],[style, lines, [points, 1]],[point_type, bullet])@}
{@plot([[discrete,[[30,7]]], -0.4*x+19],[x,0,60],[y,0,20],[style, points, lines], [color, red, blue],[point_type, asterisk])@}
{@plot([[discrete,[[10, 0.6], [20, 0.9], [30, 1.1], [40, 1.3], [50, 1.4]]], 2*%pi*sqrt(l/980)], [l,0,50],[style, points, lines], [color, red, blue],[point_type, asterisk])@}
Using different point styles.
{@plot([[discrete, [[10, .6], [20, .9], [30, 1.1],[40, 1.3], [50, 1.4]]],[discrete, [[11, .5], [15, .9], [25, 1.2],[40, 1.3], [50, 1.4]]]],[style, points],[point_type,circle,square],[color,black,green])@}
<h3>Parametric plots</h3>
{@plot([parametric, cos(t), sin(3*t), [t,0,2*%pi]], [nticks, 500])@}
<h3>Setting non-trivial options: labels on the axes and legend</h3>
{@plot([x^2/(1+x^2),diff(x^2/(1+x^2),x)],[x,-1,2],[legend,true])@}
{@plot(x*sin(1/x),[x,-1,2],[xlabel,"Independent variable"],[ylabel,"Dependent variable"],[legend,"This is a plot"])@}
<h3>Log scale for y-axis, with red colour</h3>
{@plot(exp(3*s),[s, -2, 2],[logy], [color,red])@}
<h3>Turn off the box, grid and the axes</h3>
Default options
{@plot([parametric, (exp(cos(t))-2*cos(4*t)-sin(t/12)^5)*sin(t), (exp(cos(t))-2*cos(4*t)-sin(t/12)^5)*cos(t), [t, -8*%pi, 8*%pi]], [nticks, 100])@}
<tt>[axes, false]</tt>
{@plot([parametric, (exp(cos(t))-2*cos(4*t)-sin(t/12)^5)*sin(t), (exp(cos(t))-2*cos(4*t)-sin(t/12)^5)*cos(t), [t, -8*%pi, 8*%pi]], [nticks, 100], [axes,false])@}
<tt>[box, false]</tt>
{@plot([parametric, (exp(cos(t))-2*cos(4*t)-sin(t/12)^5)*sin(t), (exp(cos(t))-2*cos(4*t)-sin(t/12)^5)*cos(t), [t, -8*%pi, 8*%pi]], [nticks, 100], [box,false])@}
<h3>Putting the axes in the middle</h3>
{@plot([x^2/(1+x^2),2*x/(1+x^2)^2], [x, -2, 2], [y,-2.1,2.1], [box, false], [yx_ratio, 1], [axes, solid], [xtics, -2, 0.5, 2],[ytics, -2, 0.5, 2])@}
```

## Piecewise functions

A piecewise function can be defined with `if`

statements.

```
/* Piecewise function at x0, with discontinuity. */
f0:x^3
f1:sin(x)
x0:2
pg1:if x<(x0-1/1000) then f0 else if x<x0+1/1000 then 5000 else f1;
```

Notes:

- Do not use functions, but instead have the conditional statement return an
*expression*. This seems odd, but Maxima's plot command plots expressions not functions. - Note the use of a small gap to create a discontinuous graph. If you want a larger gap, that is fine as well.

Now use the CASText:

```
{@plot(pg1,[x,(x0-5),(x0+5)],[y,-10,10])@}
```

For a discontinuous function, with the endpoints circled etc. try adding some of the following options.

```
f0:x^3
f1:sin(x)
x0:2
pg1:if x<(x0-1/1000) then f0 else if x<x0+1/1000 then 5000 else f1;
ps:[style, lines, points, points];
pt:[point_type,circle,circle,bullet];
pc:[color, blue,red,blue];
```

Now use the CASText:

```
{@plot([pg1, [discrete,[ [x0,ev(f0,x=x0)], [x0,ev(f1,x=x0)]]], [discrete,[ [x0,ev((f0+f1)/2,x=x0)]]] ], [x,(x0-5),(x0+5)], [y,-10,10], ps, pt, pc)@}
```

## Graph theory

It is possible to plot simple discrete graphs directly using STACK's `plot`

command by building a combination of discrete and line plots.

## implicit_plot()

In Maxima

```
load("implicit_plot");
implicit_plot(x^2+y^2=x^2*y^2+1,[x,-2,2],[y,-2,2]);
```

generates a plot of an implicit function.

Maxima's `implicit_plot()`

function does not respect the plot options, and we cannot place the resulting plot files in the correct places.
Hence, STACK does not currently support implicit plots.

## HTML

Note also that images can be included as HTML. It is easiest to place your image somewhere on the internet and include a URL in the body of your STACK question.

## Bode plots

Maxima has a very basic package for bode diagrams, try `load(bode)`

in a Maxima session. This is not a supported package, so instead you can create Bode diagrams directly with code such as the following.

```
/* Define two functions to do the plotting */
bose_gain(f,r):=block([p,w], p:plot(20*log(abs( apply(f,[%i*w]) ))/log(10), [w, r[2],r[3]], [logx]), return(p) );
bose_phase(f,r):=block([p,w], p:plot( carg( apply(f,[%i*w]))*180/%pi, [w, r[2],r[3]], [logx]), return(p) );
/* Define a transfer function */
H(s):=100*(1+s)/((s+10)*(s+100));
/* Produce the graphs */
gain: bose_gain(H,[w,1/1000,1000]);
phase:bose_phase(H,[w,1/1000,1000]);
```