6

I need to draw a bar graph using Python's turtle graphics and I figured it would be easier to simply make the pen a thick square so I could draw the bars like that and not have to worry about making dozens of rectangles and filling them in.

When I set the turtle shape using turtle.shape('square') though, it only changes the appearance of the pen but has no effect on the actual drawing:

enter image description here

Is there a way to make turtle actually draw a rectangular stroke, whether that be through built-in methods or through modifying the turtle file?

I DON'T want rounded edges, like this:

enter image description here

Matt
  • 2,953
  • 3
  • 27
  • 46

5 Answers5

5

To answer the question asked in the title: No, it is not possible to change the pen stroke directly (see cdlane's answer for a possible way to do it by modifying the hardcoded values from tkinter).

I did find a workaround for the use case presented in the question body, however.

A custom pen shape (in this case, representing the exact shape and size of the bar) can be registered like this:

screen.register_shape("bar", ((width / 2, 0), (-width / 2, 0), (-width / 2, height), (width / 2, height)))`

We can then simply loop through each bar, update the pen shape with the new values, and use turtle.stamp to stamp the completed bars onto the graph, no drawing required.

Matt
  • 2,953
  • 3
  • 27
  • 46
3

It looks like changing the shape of the pen stroke itself isn't possible. turtle.shape('square') only changes the shape of the turtle, not the pen stroke. I suggest lowering the pen size, and creating a function to draw a rectangle. You could use this do draw the bars.

austin-schick
  • 1,225
  • 7
  • 11
  • `turtle.shape("square")` works as long as you use `turtle.stamp()`--see [this answer](https://stackoverflow.com/a/42174223/6243352). – ggorlen Oct 15 '20 at 17:23
3

I've two solutions to this problem that I've used in various programs.

The first is a variation on your stamp solution. Rather than use screen.register_shape() to register a custom polygon for each line, use a square turtle and for each line turtle.turtlesize() it into the rectangle you want to stamp:

from turtle import Turtle, Screen

STAMP_SIZE = 20  # size of the square turtle shape

WIDTH, LENGTH = 25, 125

yertle = Turtle(shape="square")
yertle.penup()

yertle.turtlesize(WIDTH / STAMP_SIZE, LENGTH / STAMP_SIZE)

yertle.goto(100 + LENGTH//2, 100)  # stamps are centered, so adjust X

yertle.stamp()

screen = Screen()
screen.exitonclick()

My other solution, when I need to draw instead of stamp, is to reach into turtle's tkinter underpinning and modify turtle's hardcoded line end shape itself:

from turtle import Turtle, Screen
import tkinter as _

_.ROUND = _.BUTT

WIDTH, LENGTH = 25, 125

yertle = Turtle()
yertle.width(WIDTH)
yertle.penup()

yertle.goto(100, 100)

yertle.pendown()

yertle.forward(LENGTH)

screen = Screen()
screen.exitonclick()
cdlane
  • 40,441
  • 5
  • 32
  • 81
0

Use multiple stamps like so:

import turtle

turtle.shape("square")
for count in range(x):
    turtle.stamp()
    turtle.forward(1)
Baptiste Mille-Mathias
  • 2,144
  • 4
  • 31
  • 37
TriHrd
  • 1
0

Actually, there is an official way to do that. you can use the turtle.shape() function to set a shape. and the shapes can be registered by yourself by using the screen.register_shape('your file name') function.

  1. get a .gif file that is your intended shape, whose name is 'xxx.gif'.
  2. put this gif file into the same file as your py code file.
  3. use screen(your screen variable).register_shape('xxx.gif')
  4. turtle(your turtle variable).shape('xxx.gif'), the suffix must be followed.

then, it's done.