Is it possible to change turtle's pen stroke?
Question:
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:
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:
Answers:
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.
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.
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()
Use multiple stamps like so:
import turtle
turtle.shape("square")
for count in range(x):
turtle.stamp()
turtle.forward(1)
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.
- get a .gif file that is your intended shape, whose name is ‘xxx.gif’.
- put this gif file into the same file as your py code file.
- use screen(your screen variable).register_shape(‘xxx.gif’)
- turtle(your turtle variable).shape(‘xxx.gif’), the suffix must be followed.
then, it’s done.
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:
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:
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.
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.
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()
Use multiple stamps like so:
import turtle
turtle.shape("square")
for count in range(x):
turtle.stamp()
turtle.forward(1)
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.
- get a .gif file that is your intended shape, whose name is ‘xxx.gif’.
- put this gif file into the same file as your py code file.
- use screen(your screen variable).register_shape(‘xxx.gif’)
- turtle(your turtle variable).shape(‘xxx.gif’), the suffix must be followed.
then, it’s done.