Maxima has some built-in drawing commands, but the draw package does a much better job of graphing. Note that Maxima's graphs are not its strong point, it's much better at symbolic calculation than graphs. However, it allows you to mix graphs and calculations, whereas Winplot just does graphs and some numeric applications.
This is an introduction to some of the commands we'll use. The best resource I've found for the draw package is Graphics with Maxima by Wilhelm Haager. He explains things much better than the Maxima manual and he has images whereas the manual only has commands.
To use any of the draw commands, you must first load the draw package. You only need to load package once, probably at the beginning of the file.
load(draw)$
The following command represents the shortest command needed to graph a function \( y = x^2 \) on \(-2 \le x \le 2 \).
draw2d(
explicit(x^2,x,-2,2)
)$
The command could have been entered on one line. I like to split them up and apply some indentation to keep things straight.
The explicit command is just one of the graphic objects you can have. Some of the other objects you can have are implicit, points, label, polar, and parametric. The following picture will demonstrate the use of some of them.
draw2d(
grid = true,
color = red,
explicit(x^2,x,-2,2),
color = blue,
line_width = 2,
implicit(x^2+y^2=4,x,-2,2,y,-2,2),
color = forest_green,
point_size = 3,
point_type = filled_circle,
points([ [-1,-1], [2,2] ]),
color = orange,
label(["HI",0,1]),
parametric(t,t^(1/3),t,-2,2)
)$
The first thing you probably notice on that last graph is not how many cool features you can have, but how the circle looks like an ellipse. That's because the viewing window isn't square. There are two sets of commands that alter that: dimensions and xrange/yrange. The dimensions give the actual size of the plot window in pixels. The default is 600 pixels wide by 500 pixels high. The xrange/yrange are overrides for the viewing window that Maxima picks. For what we've been doing so far, it decided that the window [-2,2]×[-2,4] covers the entire graph. That's 4 units wide by 6 units high. So we're trying to fit a 4×6 picture into a 6×5 frame and it just doesn't look that good.
Here are two more pictures. The first added a dimension statement to try to make the dimensions of the image match the dimensions of the graph. It's better, but still not perfect.
draw2d(
dimensions = [400,600],
grid = true,
color = red,
explicit(x^2,x,-2,2),
color = blue,
line_width = 2,
implicit(x^2+y^2=4,x,-2,2,y,-2,2),
color = forest_green,
point_size = 3,
point_type = filled_circle,
points([ [-1,-1], [2,2] ]),
color = orange,
label(["HI",0,1]),
parametric(t,t^(1/3),t,-2,2)
)$
The image contains more than just the plot, it contains labels as well, so things didn't come out exactly right. A better solution is to add dimensions and then change the viewing window to be square as well. This is the same graph as before, only the first three lines are different. Technically, the yrange isn't needed since [-2,4] is what Maxima chose.
draw2d(
dimensions = [600,600],
xrange = [-3,3],
yrange = [-2,4],
grid = true,
color = red,
explicit(x^2,x,-2,2),
color = blue,
line_width = 2,
implicit(x^2+y^2=4,x,-2,2,y,-2,2),
color = forest_green,
point_size = 3,
point_type = filled_circle,
points([ [-1,-1], [2,2] ]),
color = orange,
label(["HI",0,1]),
parametric(t,t^(1/3),t,-2,2)
)$
You may have noticed the axes don't really show up any differently than the other grid lines. Here are some examples to show how to control the axes, as well as the smoothness of a graph using nticks or ip_grid (for an implicit plot). One of the downfalls is the font: you can only have one font and one font size for the entire graph (including labels and tick values).
draw2d(
xaxis = true, xaxis_width = 2, xaxis_type = solid, xaxis_color = red,
yaxis = true, yaxis_width = 5, yaxis_type = dots, yaxis_color = purple,
dimensions = [600,600],
xrange = [-3,3],
yrange = [-3,3],
grid = true,
color = blue,
ip_grid = [4,4],
implicit(x^2+y^2=4,x,-2,2,y,-2,2),
color = red,
nticks = 9,
parametric(2.5*cos(t),2.5*sin(t),t,0,2*%pi),
color = forest_green,
nticks = 18,
polar(1.5,t,0,2*%pi),
font = "Arial",
font_size = 16
)$
Mathematically, those three graphs are all circles. The implicit plot \( x^2 + y^2 = 4 \) gives the worst results and is the least efficient. A better way would be using parametric plots \( x = 2.5 \cos t,\ y = 2.5 \sin t \) or, the best way, the polar graph \( r = 1.5 \).
The draw2d command has the ability to shade a region for an explicitly defined function.
draw2d(
fill_color = red,
filled_func = 2+sin(x),
explicit(cos(x),x,-%pi/2,%pi/2),
filled_func = false,
line_width = 2,
color = black,
explicit(cos(x),x,-%pi,%pi),
color = blue,
explicit(2+sin(x),x,-%pi,%pi)
)$
You will notice that most of the commands have to do with formatting the graph, rather than actually drawing it. Commonly used items like the axes, grid, and dimensions; as well as lesser used items like the resolution (nticks or ip_grid), line_width, default color (if you don't like blue), and font and font_size, can all be moved into a separate block that will establish them as defaults for all graphs that come after that point.
The command that makes that possible is set_draw_defaults() and anything you put into that block will become the defaults for new graphs unless you change them. Basically, anything that you find yourself typing over and over would be a good candidate for moving into the set_draw_defaults() block.
For a single graph, it may not make that much difference, but if you want to generate multiple graphs that look similar, it can save a lot of coding.
load(draw)$
draw2d(
explicit(x*sin(x)^2,x,-2,2)
)$
set_draw_defaults(
xaxis = true, xaxis_color = orange,
xaxis_type = solid, xaxis_width = 1, xtics = 1,
yaxis = true, yaxis_color = orange,
yaxis_type = solid, yaxis_width = 1, ytics = 1,
dimensions = [600,600],
grid = true,
nticks = 250,
ip_grid = [100,100],
font = Arial,
font_size = 14,
line_width = 3
)$
draw2d(
explicit(x*sin(x)^2,x,-2,2)
)$
draw2d(
yrange = [-2,2],
explicit(x*sin(x)^2,x,-2,2)
)$
Here is the same graph three times. The first one is the original graph from Maxima without any additional formatting since it comes before the set_draw_defaults() command. The others come after set_draw_defaults() so they include the formatting commands from that. The last one adds a yrange statement to make the graph more square and to show that you can add additional graphic commands, even if you include the set_draw_defaults(). If you include a graphics command in the set_draw_defaults() and in the draw2d() both, the one inside the draw2d() will override the default.
The draw commands can be prefaced with a "wx" to draw them inside of wxMaxima instead of in a separate window. This may speed up development time. The graphs are generally not as nice looking, though. There is a bigger issue with this: When Richland installed Maxima, they installed it to a default location and the wxdraw2d() commands don't actually work. However, if you install your own copy of Maxima at home, they should work there and they work on the instructor's computer when he goes to grade them.
If you use the draw2d() instead of wxdraw2d(), you have to close your graph before any changes inside wxMaxima will be recognized. That extra step of closing the graph is easy to forget, which is why wxdraw2d() might be quicker for development purposes.