# MicroPython Displays: Drawing Shapes

## Overview

Warning: 

https://www.youtube.com/watch?v=XVcgVg4sy7s

![](https://cdn-learn.adafruit.com/assets/assets/000/037/395/medium800/micropython_IMG_5622.jpg?1479508822)

So you have a nifty&nbsp;display like a bright TFT LCD, Charlieplex LED or NeoPixel matrix powered by MicroPython, but what if you want to draw shapes and graphics&nbsp;on it? &nbsp;Most MicroPython display modules only give you basic pixel drawing commands so it's difficult&nbsp;to draw graphics&nbsp;yourself pixel by pixel. &nbsp;Luckily there's a handy new [MicroPython graphics module](https://github.com/adafruit/micropython-adafruit-gfx) you can use to draw basic shapes and graphics&nbsp;on any pixel-based display! &nbsp;This module shows some of the power of MicroPython--a single module&nbsp;can work with **any** pixel display because of MicroPython's dynamic language features. &nbsp;In this guide you'll learn how to use a MicroPython graphics&nbsp;module to draw basic line, rectangle, circle, and triangle shapes on pixel-based displays like the [ILI9341 TFT FeatherWing](https://www.adafruit.com/product/3315).

To follow this guide you'll want to be familiar with MicroPython&nbsp;by reading these&nbsp;guides:

- [MicroPython Basics: What is MicroPython?](../../../../micropython-basics-what-is-micropython)
- [MicroPython Basics: How to Load MicroPython on a Board](../../../../micropython-basics-how-to-load-micropython-on-a-board)
- [MicroPython Basics: Load Files & Run Code](../../../../micropython-basics-load-files-and-run-code)

See [all the MicroPython guides in the learning system](../../../../category/micropython) for more information.

In addition be sure to follow the guide for your pixel-based display first:

- [MicroPython Hardware: LED Backpacks & FeatherWings](../../../../micropython-hardware-led-backpacks-and-featherwings)
- [MicroPython Hardware: Charlieplex LED Matrix](../../../../micropython-hardware-charlieplex-led-matrix)
- [MicroPython Hardware: SSD1306 OLED Display](../../../../micropython-hardware-ssd1306-oled-display)
- [MicroPython Hardware: ILI9341 TFT & FeatherWing](../../../../micropython-hardware-ili9341-tft-and-featherwing)

# MicroPython Displays: Drawing Shapes

## Hardware

For this guide there's no special hardware you need to draw graphics&nbsp;on a display. &nbsp;However you do need to have a pixel-based display of some sort (LED, TFT, NeoPixel--anything!) connected to your MicroPython board. &nbsp;Check out the following guides for details on how to use a few pixel displays with MicroPython:

- [MicroPython Hardware: LED Backpacks & FeatherWings](../../../../micropython-hardware-led-backpacks-and-featherwings)
- [MicroPython Hardware: Charlieplex LED Matrix](../../../../micropython-hardware-charlieplex-led-matrix)
- [MicroPython Hardware: SSD1306 OLED Display](../../../../micropython-hardware-ssd1306-oled-display)
- [MicroPython Hardware: ILI9341 TFT & FeatherWing](../../../../micropython-hardware-ili9341-tft-and-featherwing)

Follow the appropriate guide to setup the hardware and make sure you can draw pixels on the display with MicroPython before continuing.

# MicroPython Displays: Drawing Shapes

## Software

# Install Module

To&nbsp;use the graphics&nbsp;module&nbsp;with your MicroPython board you'll need to install the [micropython-adafruit-gfx&nbsp;MicroPython module](https://github.com/adafruit/micropython-adafruit-gfx)&nbsp;on your board.

First make sure you are running the latest version of MicroPython for your board. &nbsp;If you're using the&nbsp; **ESP8266 MicroPython** port you **must** be running version **[1.8.5 or higher](http://micropython.org/download#esp8266)** as earlier versions do not support using .mpy modules as shown in this guide. &nbsp;

Download the latest **gfx.mpy** &nbsp;file&nbsp;from the&nbsp;[releases page](https://github.com/adafruit/micropython-adafruit-gfx/releases) of the [micropython-adafruit-gfx GitHub repository](https://github.com/adafruit/micropython-adafruit-gfx/).

If your board supports USB mass storage, like the SAMD21 MicroPython port, then simply drag the .mpy and other files to the board's file system (eject the drive and reset the board to make sure it is picked up by MicroPython).

If your board doesn't support USB mass storage, like ESP8266 MicroPython boards, then [use a tool like ampy to copy the file to the board](../../../../micropython-basics-load-files-and-run-code/overview).

# Usage

The following section will show how to draw shapes&nbsp;on a ILI9341 TFT&nbsp;display like the TFT FeatherWing. &nbsp;You'll see how the module can be adpated to draw on any pixel-based display by plugging in a new pixel drawing function too.

First [connect to the board's serial REPL](../../../../micropython-basics-how-to-load-micropython-on-a-board/serial-terminal)so you are at the MicroPython **\>\>\>** prompt.

# Display Initialization

Next you'll need to initialize your display so that you can draw pixels on it. [Consult the MicroPython display guides](../../../../micropython-displays-drawing-shapes/hardware)&nbsp;for details on initializing displays. &nbsp;

For example the ILI9341 TFT&nbsp;FeatherWing display initialization on ESP8266 MicroPython might look like:

```auto
import machine
import ili9341
spi = machine.SPI(1, baudrate=32000000)
display = ili9341.ILI9341(spi, cs=machine.Pin(0), dc=machine.Pin(15))
```

Once you have a display&nbsp;object which has a function to draw pixels you're ready to start drawing&nbsp;shapes.

# Graphics Initialization

To use the graphics and shape&nbsp;rendering module you'll need to import its module and create an instance of the **GFX** &nbsp;class inside it. &nbsp;For example to create a graphics renderer&nbsp;for the TFT FeatherWing&nbsp;above you would run:

```auto
import gfx
graphics = gfx.GFX(240, 320, display.pixel)
```

The **GFX** &nbsp;class initializer takes three parameters:

1. **The maximum width of the display in pixels** , in this case 240&nbsp;for the TFT&nbsp;FeatherWing.
2. **The maximum height of the display in pixels** , in this case 320&nbsp;for the TFT&nbsp;FeatherWing.
3. **A pixel drawing function to call when the GFX&nbsp;class needs to write a pixel.** &nbsp;For this example the TFT display&nbsp;class **pixel** function is specified. &nbsp;It's important to note that to use the graphics&nbsp;class you **must** have a function it can call to draw pixels! &nbsp;This function can live anywhere, like as a global function or on a class instance. &nbsp;The function needs to take at least a pixel x position and pixel y position parameter (in that order), and any number of other positional and keyword parameters after them (like color, intensity, etc.).

There are two optional parameters you can specify as keyword arguments too. &nbsp;They aren't shown in this guide but see how the [ILI9341 display example code](https://github.com/adafruit/micropython-adafruit-gfx/blob/master/examples/ili9341_test.py)uses them:

- **hline** - Optionally set hline to a fast horizontal line drawing function for your display. &nbsp;This will improve the speed of drawing certain shapes. &nbsp;The function should take&nbsp;as parameters&nbsp;an x position and y position of the line start, then width of the line in pixels. &nbsp;Any number of optional color or other parameters can follow. &nbsp;If you don't provide a hline function a slow default implementation that draws pixel by pixel will be used.
- **vline** - Optionally set vline to a fast vertical line drawing function for your display. &nbsp;This will improve the speed of drawing certain shapes, especially filled shapes. &nbsp;The function should take as parameters an x position, y position of the line start, then height of the line in pixels. &nbsp;Any number of optional color or other parameters can follow. &nbsp;If you don't provide a vline function a slow default implementation that draws pixel by pixel will be used.

# Drawing Shapes

Now the fun begins! &nbsp;After creating the GFX class you can call functions to draw shapes on the display. &nbsp;For example draw a simple line across the entire display with the **line** function:

```auto
display.fill(0)  # Clear the display
graphics.line(0, 0, 239, 319, ili9341.color565(255, 0, 0))
```

![](https://cdn-learn.adafruit.com/assets/assets/000/037/386/medium800/micropython_IMG_5612.jpg?1479508248)

The **line** function takes the following parameters:

- **X position of the line start.**
- **Y position of the line start.**
- **X position of the line end.**
- **Y position of the line end.**
- **Any number of color or other parameters that will be passed to the pixel drawing function. &nbsp;** In this case a red color for the display is specified.

Draw an empty rectangle with the **rect** function:

```auto
display.fill(0)  # Clear the display
graphics.rect(0, 0, 120, 160, ili9341.color565(0, 255, 0))
```

![](https://cdn-learn.adafruit.com/assets/assets/000/037/388/medium800/micropython_IMG_5613.jpg?1479508298)

The **rect** function takes the following parameters:

- **X position of the rectangle upper left corner.**
- **Y position of the rectangle upper left corner.**
- **Width of the rectangle in pixels.**
- **Height of the rectangle in pixels.**
- **Any number of color other parameters that will be passed to the pixel drawing function.** &nbsp;In this case a green color for the display is specified.

You can also draw a filled rectangle with the **fill\_rect** function. &nbsp;The parameters are exactly the same as the rect function but now the rectangle is drawn as a solid shape:

```auto
display.fill(0)  # Clear the display
graphics.fill_rect(0, 0, 120, 160, ili9341.color565(0, 255, 0))
```

![](https://cdn-learn.adafruit.com/assets/assets/000/037/389/medium800/micropython_IMG_5614.jpg?1479508317)

Draw a circle with the **circle** function:

```auto
display.fill(0)  # Clear the display.
graphics.circle(120, 160, 60, ili9341.color565(0, 0, 255))
```

![](https://cdn-learn.adafruit.com/assets/assets/000/037/390/medium800/micropython_IMG_5615.jpg?1479508336)

The **circle** &nbsp;function takes the following parameters:

- **X position of the circle center.**
- **Y position of the circle center.**
- **Radius of the circle in pixels.**
- **Any number of color other parameters that will be passed to the pixel drawing function.** &nbsp;In this case a blue&nbsp;color for the display is specified.

It's no surprise there's a **fill\_circle** function to draw a filled circle. &nbsp;This function takes exactly the same parameters as the circle function but will draw a solid shape:

```auto
display.fill(0)  # Clear the display
graphics.fill_circle(120, 160, 60, ili9341.color565(0, 0, 255))
```

![](https://cdn-learn.adafruit.com/assets/assets/000/037/391/medium800/micropython_IMG_5617.jpg?1479508379)

Draw a triangle with the **triangle** function:

```auto
display.fill(0)  # Clear the display
graphics.triangle(120, 100, 180, 160, 60, 160, ili9341.color565(255, 0, 255))
```

![](https://cdn-learn.adafruit.com/assets/assets/000/037/392/medium800/micropython_IMG_5618.jpg?1479508392)

The **triangle** &nbsp;function takes the following parameters:

- **X position of&nbsp;the first point in the triangle.**
- **Y position of the first point in the triangle.**
- **X position of the second point in the triangle.**
- **Y position of the second point in the triangle.**
- **X position of the third point in the triangle.**
- **Y position of the third point in the triangle.**
- **Any number of color other parameters that will be passed to the pixel drawing function.** &nbsp;In this case a pink&nbsp;color for the display is specified.

And a **fill\_triangle** function exists to draw a filled triangle too. &nbsp;This function takes exactly the same parameters as the triangle function but will draw a solid shape:

```auto
display.fill(0)  # Clear the display
graphics.fill_triangle(120, 100, 180, 160, 60, 160, ili9341.color565(255, 0, 255))
```

![](https://cdn-learn.adafruit.com/assets/assets/000/037/393/medium800/micropython_IMG_5619.jpg?1479508410)

That's all there is to basic shape drawing with the Adafruit MicroPython GFX module! &nbsp;With these basic shape primitives you can start to create interesting graphic projects, like a pong or breakout game using filled rectangles and circles. &nbsp;You can add text with the [Adafruit MicroPython bitmap font module](../../../../micropython-displays-drawing-text) too!

Remember any pixel-based display can be used with this library, for example an OLED display or NeoPixel, Charlieplex&nbsp;LED, or simple LED backpack matrix are great targets to use with the library. &nbsp;Just plug in each module's pixel function and you'll be drawing shapes in no time!


## Related Guides

- [Adafruit Feather HUZZAH ESP8266](https://learn.adafruit.com/adafruit-feather-huzzah-esp8266.md)
- [Adafruit Feather M0 Adalogger](https://learn.adafruit.com/adafruit-feather-m0-adalogger.md)
- [Adafruit Feather M0 Bluefruit LE](https://learn.adafruit.com/adafruit-feather-m0-bluefruit-le.md)
- [Adafruit OLED FeatherWing](https://learn.adafruit.com/adafruit-oled-featherwing.md)
- [Adafruit 2.4" TFT FeatherWing](https://learn.adafruit.com/adafruit-2-4-tft-touch-screen-featherwing.md)
- [MIDI Solenoid Drummer](https://learn.adafruit.com/midi-solenoid-drummer.md)
- [Animated LED Sand](https://learn.adafruit.com/animated-led-sand.md)
- [Adafruit IO Environmental Monitor for Feather or Raspberry Pi](https://learn.adafruit.com/adafruit-io-air-quality-monitor.md)
- [Feather-based Hue lighting controller](https://learn.adafruit.com/feather-hue-lighting-controller.md)
- [Which CircuitPython Board is Right for You?](https://learn.adafruit.com/choose-your-circuitpython-board.md)
- [Using Crickit and Adafruit IO together](https://learn.adafruit.com/crickit-and-adafruitio.md)
- [Adding a WiFi Co-Processor to CircuitPython](https://learn.adafruit.com/adding-a-wifi-co-processor-to-circuitpython-esp8266-esp32.md)
- [CircuitPython Display_Text Library](https://learn.adafruit.com/circuitpython-display-text-library.md)
- [I Vote(d) Pin](https://learn.adafruit.com/i-vote-d-pin.md)
- [Square NeoPixel Display with Black LED Acrylic](https://learn.adafruit.com/sqaure-neopixel-display-with-black-led-acrylic.md)
- [Adafruit IO Home: Lights and Temperature ](https://learn.adafruit.com/adafruit-io-house-lights-and-temperature.md)
- [Guardian Shield+ Zelda Breath of the Wild](https://learn.adafruit.com/guardian-shield-zelda-breath-of-the-wild.md)
- [Bluetooth Remote Control for the Lego Droid Developer Kit](https://learn.adafruit.com/bluetooth-remote-for-lego-droid.md)
- [Adafruit IO Home: Security ](https://learn.adafruit.com/adafruit-io-home-security.md)
- [Wireless UNTZtrument Using BLE MIDI ](https://learn.adafruit.com/wireless-untztrument-using-ble-midi.md)
