<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 .. _canvas-layout
Step1:  If you need greater control over the positioning of the axes within the canvas, or want to add multiple axes to one canvas, it's necessary to create the canvas and axes explicitly, then use the axes to plot your data.  For example, you can use the bounds argument to specify explicit (xmin, xmax, ymin, ymax) bounds for the axes using canvas coordinates (note that canvas coordinates always increase from top to bottom, unlike cartesian coordinates)
Step2:  You can also use negative values to specify values relative to the right and bottom sides of the canvas, instead of the (default) left and top sides, greatly simplifying the layout
Step3:  Furthermore, the bounds parameters can use any 
Step4:  Of course, most of the time this level of control isn't necessary.  Instead, the grid argument allows us to easily position each set of axes on a regular grid that covers the canvas.  Note that you can control the axes position on the grid in a variety of ways
Step5:  You can also use the gutter argument to control the space between cells in the grid
Step6:  Sometimes, particularly when embedding axes to produce a figure-within-a-figure, the corner argument can be used to position axes relative to one of eight "corner" positions within the canvas.  The corner argument takes a (position, inset, width, height) tuple
Step7:  Here are all the positions supported by the corner argument
<ASSISTANT_TASK:>
Python Code:
import numpy
y = numpy.linspace(0, 1, 20) ** 2
import toyplot
toyplot.plot(y, width=300);
Explanation: .. _canvas-layout:
Canvas Layout
In Toyplot, axes (including :ref:cartesian-axes, :ref:table-axes, and others) are used to map data values into canvas coordinates.  The axes range (the area on the canvas that they occupy) is specified when they are created. By default, axes are sized to fill the entire canvas:
End of explanation
canvas = toyplot.Canvas(width=600, height=300)
axes1 = canvas.axes(bounds=(20, 280, 20, 280))
axes1.plot(y)
axes2 = canvas.axes(bounds=(320, 580, 20, 280))
axes2.plot(1 - y);
Explanation: If you need greater control over the positioning of the axes within the canvas, or want to add multiple axes to one canvas, it's necessary to create the canvas and axes explicitly, then use the axes to plot your data.  For example, you can use the bounds argument to specify explicit (xmin, xmax, ymin, ymax) bounds for the axes using canvas coordinates (note that canvas coordinates always increase from top to bottom, unlike cartesian coordinates):
End of explanation
canvas = toyplot.Canvas(width=600, height=300)
axes1 = canvas.axes(bounds=(20, 280, 20, -20))
axes1.plot(y)
axes2 = canvas.axes(bounds=(-280, -20, 20, -20))
axes2.plot(1 - y);
Explanation: You can also use negative values to specify values relative to the right and bottom sides of the canvas, instead of the (default) left and top sides, greatly simplifying the layout:
End of explanation
canvas = toyplot.Canvas(width="20cm", height="2in")
axes1 = canvas.axes(bounds=("1cm", "5cm", "10%", "90%"))
axes1.plot(y)
axes2 = canvas.axes(bounds=("6cm", "-1cm", "10%", "90%"))
axes2.plot(1 - y);
Explanation: Furthermore, the bounds parameters can use any :ref:units, including "%" units, so you can use real-world units and relative dimensioning in any combination that makes sense:
End of explanation
canvas = toyplot.Canvas(width=600, height=300)
axes1 = canvas.axes(grid=(1, 2, 0))
axes1.plot(y)
axes2 = canvas.axes(grid=(1, 2, 1))
axes2.plot(1 - y);
Explanation: Of course, most of the time this level of control isn't necessary.  Instead, the grid argument allows us to easily position each set of axes on a regular grid that covers the canvas.  Note that you can control the axes position on the grid in a variety of ways:
(rows, columns, n)
fill cell $n$ (in left-to-right, top-to-bottom order) of an $M \times N$ grid.
(rows, columns, i, j)
fill cell $i,j$ of an $M \times N$ grid.
(rows, columns, i, rowspan, j, colspan)
fill cells $[i, i + rowspan), [j, j + colspan)$ of an $M \times N$ grid.
End of explanation
canvas = toyplot.Canvas(width=600, height=300)
axes1 = canvas.axes(grid=(1, 2, 0), gutter=15)
axes1.plot(y)
axes2 = canvas.axes(grid=(1, 2, 1), gutter=15)
axes2.plot(1 - y);
Explanation: You can also use the gutter argument to control the space between cells in the grid:
End of explanation
x = numpy.random.normal(size=100)
y = numpy.random.normal(size=100)
canvas = toyplot.Canvas(width="5in")
canvas.axes().plot(numpy.linspace(0, 1) ** 0.5)
canvas.axes(corner=("bottom-right", "1in", "1.5in", "1.5in")).scatterplot(x, y);
Explanation: Sometimes, particularly when embedding axes to produce a figure-within-a-figure, the corner argument can be used to position axes relative to one of eight "corner" positions within the canvas.  The corner argument takes a (position, inset, width, height) tuple:
End of explanation
canvas = toyplot.Canvas(width="10cm")
for position in ["top-left", "top", "top-right", "right", "bottom-right", "bottom", "bottom-left", "left"]:
    canvas.axes(corner=(position, "1cm", "2cm", "2cm"), label=position)
Explanation: Here are all the positions supported by the corner argument:
End of explanation
<END_TASK>