Graphics Reference


Intro: Tk

One of the most common libraries to create graphics in Python is called Tk (short for "tkinter"). Tk is a powerful graphics library that should be automatically installed for Windows and Mac along with Python when you installed it. While Tk's great, some of the functions are hard to use. For this reason, we provide our own small graphics library that is built on top of Tk and makes it easier to use. It's not a replacement for Tk - it just adds a few new functions to make certain things like drawing text easier. You can always explore the full Tk library if you're interested in seeing what else you can do!

While any graphics projects we create for you will have the necessary graphics files included, you can also download this graphics file, unzip it, and add graphics.py to your project folder if you're starting from scratch. Then, all you need to do is add from graphics import Canvas to the top of your code.

Importing

To use our graphics library, you must first import it at the top of your program, by adding this line of code to the top of your file:

from graphics import Canvas

The Canvas

The drawing model for the graphics library is a "canvas" (much like a painting) where you are going to draw various shapes. The canvas is a grid of pixels that have x and y values. The coordinate (0, 0) is in the upper-left-hand corner of the canvas. The values of x increase as you move to the right. The values of y increase as you move down. In other words, you can think of the canvas as follows:

alt x and y axes of canvas extending right and down, starting from the upper left"

When we want to draw shapes on a canvas, we call functions on that canvas that “create” the shape we want to draw. These shapes then appear on the canvas. We will generally provide the code that creates the canvas for you, so all you need to worry about is adding shapes to that canvas. For the remainder of this handout, we will assume that a variable named canvas has already been created, and it represents the canvas that you'll be drawing on. Usually this will be done with the following provided code:

# create a new canvas
canvas = Canvas()

# get the width and height of our canvas, in pixels
canvas_width = canvas.get_width()
canvas_height = canvas.get_height()

# call this at the end of the program to make the window show
canvas.mainloop()

When we create the canvas, we can optionally specify its width and height, as well as a title that will appear at the top of the canvas window. For example, to make a canvas that's 800 pixels wide and 200 pixels tall, with the title 'My Canvas', you would do the following:

canvas = Canvas(800, 200, 'My Canvas')

alt Canvas with size 800, 200 and title 'My Canvas'

Below we provide a brief tour of some of the different shapes you can draw on a canvas as well as highlight a few of the options you have with regard to how those shapes look.

Drawing Lines

To draw lines on the canvas, use create_line and specify the coordinates for the start and end points of the line and the line's color as a string. For example, the following command would draw a black line from location (10, 20) to (100, 50) on the canvas:

canvas.create_line(10, 20, 100, 50, 'black')

alt line drawn on the canvas from (10, 20) to (100, 50)

By default, all lines are drawn in black if you omit the color parameter.

Drawing Rectangles

To draw a rectangle on the canvas, use create_rectangle and specify the coordinates for the top left corner and bottom right corner of the rectangle, as well as a color as a string. For example, the following command would draw a yellow rectangle with upper left-hand corner at (5, 50) and lower right-hand corner at (100, 200) on the canvas:

canvas.create_rectangle(5, 50, 100, 200, 'yellow')

alt yellow rectangle with upper left corner at (5, 50) and lower right corder at (100, 200)

By default, all rectangles are drawn in black if you omit the color parameter.

Drawing Ovals

To draw an oval on the canvas, use create_oval and specify the coordinates for the top left corner and bottom right corner of the bounding box containing the oval you would like to draw. In other words, the oval drawn will have its top, bottom, right, and left just touching the sides of the bounding box you specify. You'll also specify a color as in the previous functions. For example, the following command would draw a red oval that fits within an imaginary rectangle with upper left-hand corner at (5, 50) and lower right-hand corner at (100, 200) on the canvas:

canvas.create_oval(5, 50, 100, 200, 'red')

Here's what this code would draw on the canvas - note that we can think of this as an imaginary bounding box from (5, 50) to (100, 200), with an oval drawn inside it:

alt red oval that would fit perfectly within a bounding box with upper left corner at (5, 50) and lower right corder at (100, 200)

By default, all ovals are drawn in black if you omit the color parameter.

To make clear the notion of a bounding box, below we draw the same red oval and yellow rectangle from before, where both the oval and rectangle have the same coordinates. Notice how the rectangle is like a bounding box around the oval with the same coordinates.

canvas.create_rectangle(5, 50, 100, 200, 'yellow')
canvas.create_oval(5, 50, 100, 200, 'red')

alt red oval drawn on top of yellow rectangle, which serves at a bounding box for the oval

Drawing Text

To draw text on the canvas, use create_text to specify an x and y coordinate, and the following parameters:

  • anchor
  • font
  • text
  • color (optional, defaults to black)

The anchor is a string, one of "n", "ne", "e", "se", "s", "sw", "w", "nw", or "center", that describes what side of your text you want to position at the (x, y) you provide. Font describes the style and size of the text, for example 'Helvetica 32'. The text is the text string you want to appear on the screen. Here's a sample call of create_text with all of the necessary parameters (this is all one line, we've just split it to fit on the page):

canvas.create_text(50, 50, anchor='w', font='Arial 50', text='My first text!', color='blue')

alt blue text on the canvas

Adding Images

You can add image files to your canvas as well. To do this, use create_image (if you want the image to be the same size on the canvas as the image file) or create_image_with_size (if you want the image to be another size you specify). Both require you to specify the x and y location of the upper-left corner of the image on the canvas, as well as the name of the image file. create_image_with_size also requires a width and a height that the image should be. Here's an example that adds a smiley-face image to the canvas with upper-left corner at (25, 30), assuming we have an image file named "smiley.jpg" in our PyCharm project:

# create image with default dimensions
canvas.create_image(25, 30, 'smiley.png')

# or add with specific dimensions width = 100, height = 300
canvas.create_image_with_size(25, 30, 100, 300, 'smiley.png')

Here's what this code would draw on the canvas - note that the larger smiley is the one from the create_image call (the original image was 216 by 216 pixels), and the distorted one is the 100x300 smiley drawn with create_image_with_size:

alt two smiley face emojis, one is a square and one is stretched in the vertical direction

One note about Tk images is that they cannot be resized after you create them.

Note: If images do not work in your program and you're getting an error, you may not have installed the library necessary for images to work. Make sure you've installed the necessary library by running python3 -m pip install Pillow in your terminal (use py or python instead of python3 if you're on Windows).

Removing Objects From the Canvas

You can remove objects from the canvas using delete:

rect = canvas.create_rectangle(100, 200, 300, 400, 'yellow')
...
canvas.delete(rect)

Note that deleting an object is permanent - if you want to temporarily make an object hidden, use set_hidden. You can pass in either True or False to set an object to be hidden or visible:

rect = canvas.create_rectangle(100, 200, 300, 400, 'yellow')
canvas.set_hidden(rect, True)  # no longer visible
...
canvas.set_hidden(rect, False) # visible again

Object Ordering

Objects are drawn on the canvas in the order in which they are created by your code. So, if you draw a red rectangle after a yellow circle, the red rectangle can potentially cover (occlude) part of the yellow circle. This is sometimes referred to as the z-order of the objects.

As an example, below, we first draw a yellow rectangle, then draw an orange oval (which partly overlaps the rectangle), and then some text (that is on top of both the rectangle and the oval).

canvas.create_rectangle(10, 50, 200, 300, 'yellow')
canvas.create_oval(100, 100, 300, 350, 'red')
canvas.create_text(70, 170, anchor='sw', font='Arial 30', text='yay!')

alt "overlapping objects, from back to front, a yellow rectangle, a red oval overlapping but offset, and black text on top of both rectangle and oval

Changing Object Colors

Sometimes, we'll want to refer to an object after we've created it, like when we want to change an object's color later in the program. In that case, it's a good idea to store that object in a variable for us to use later. If we know we'll want to change the color of a rectangle after we've created it, we might store that object in a variable called rect and use the set_color function to change its color like this:

rect = canvas.create_rectangle(0, 0, 50, 100, 'yellow')
...
canvas.set_color(rect, 'red')

We can also individually change the outline or fill of an object using the set_fill_color and set_outline_color functions as follows:

rect = canvas.create_rectangle(0, 0, 50, 100, 'yellow')
...
canvas.set_fill_color(rect, 'red')
canvas.set_outline_color(rect, 'blue')

Here's a list of all the colors you can use in Tk.

Getting Information About Objects

For all graphical objects, you can ask the canvas for information about them. For instance, you can get an object's dimensions via get_obj_width and get_obj_height:

rect = canvas.create_rectangle(0, 0, 50, 100, 'yellow')
print(canvas.get_obj_width(rect))  # prints 50
print(canvas.get_obj_height(rect)) # prints 100

You can also ask the canvas for information about an object's location. Specifically, you can get the left-most x coordinate of the object, or the top-most y coordinate as follows:

oval = canvas.create_oval(5, 10, 50, 100, 'red')
print(canvas.get_left_x(oval))  # prints 5
print(canvas.get_top_y(oval))   # prints 10

Note that for something like an oval, the dimensions and left corner are from the bounding box that contains it.

Moving Graphical Objects

You can change the location of an object using moveto. You specify new x and y coordinates, which will be the upper-left corner of the bounding box for the object (e.g. bounding box for an oval, bounding box for a line, etc.). Here's how we would move a rect to have upper-left corner at (25, 50):

rect = canvas.create_rectangle(100, 200, 300, 400, 'yellow')
canvas.moveto(rect, 25, 50)  # moves upper left to 25, 50`

You can also change the location of an object by specifying how much you would like to move it by, instead of specifying the new location. The move function lets you specify the change in x and the change in y for the object, relative to its current location. For example, here's how we would move a rectangle 5 pixels to the right, and 10 pixels down:

rect = canvas.create_rectangle(100, 200, 300, 400, 'yellow')
canvas.move(rect, 5, 10)  # moves upper left to 105, 210