在 Python 中使用 turtle.write 时如何移动文本?

How to move text around when using turtle.write in Python?

我正在尝试解决 'Think Python'(版本:http://openbookproject.net/thinkcs/python/english3e/conditionals.html)第 5 章中的练习 9。它涉及从 turtle.write 周围移动文本,因此当值为负时它不会与条形图重叠。我曾尝试使用三重引号“"like this"””在文本前添加额外的行,但额外的行放在了错误的位置。请帮忙?

import turtle
wn=turtle.Screen()
wn.bgcolor("lightgreen")
wn.title("Barcharts FTW")
pen=turtle.Turtle()
pen.hideturtle()
pen.color("blue","red")
pen.pensize(2)
pen.penup()
pen.goto(-300,-100)

def draw_bar (t,height):
    t.pendown()
    t.begin_fill()
    t.lt(90)
    t.fd(height)
    t.write("   " + str(height))
    t.rt(90)
    t.fd(40)
    t.rt(90)
    t.fd(height)
    t.end_fill()
    t.lt(90)
    t.penup()
    t.fd(10)

xs = [48, 117, 200, 240, -160, 260, 220]
for v in xs:
    draw_bar(pen,v)

wn.mainloop()

只需移动乌龟在不同的地方写文字

t.penup()
if height < 0: 
   t.fd(-15)
t.write("   " + str(height))
if height < 0: 
   t.fd(15)
t.pendown()

完整代码

import turtle

# --- functions ---

def draw_bar(t, height):
    t.pendown()
    t.begin_fill()
    t.lt(90)
    t.fd(height)

    t.penup()
    if height < 0:
        t.fd(-15)
    t.write("   " + str(height))
    if height < 0:
        t.fd(15)
    t.pendown()

    t.rt(90)
    t.fd(40)
    t.rt(90)
    t.fd(height)
    t.end_fill()
    t.lt(90)
    t.penup()
    t.fd(10)

# --- main ---

wn = turtle.Screen()
wn.bgcolor("lightgreen")
wn.title("Barcharts FTW")

pen = turtle.Turtle()
pen.hideturtle()
pen.color("blue","red")
pen.pensize(2)
pen.penup()
pen.goto(-300,-100)

xs = [48, -117, 200, 240, -160, 260, 220]
for v in xs:
    draw_bar(pen, v)

wn.mainloop()

@Laura,下面是使用 stamping 而不是 drawing 构建条形图的不同方法。它还有一些其他功能可能对您有用,无论您是绘制还是标记:它根据数据本身计算在 window 中将图形居中的位置;它使用 turtle.write()align="center" 功能将标签与条形对齐;它明确设置字体而不是使用几乎不可读的默认值:

from turtle import Turtle, Screen

BAR_WIDTH = 40
BAR_SPACING = 10

FONTSIZE = 12
FONT = ('Arial', FONTSIZE, 'bold')

STAMP_UNIT = 20

xs = [48, -117, 200, 240, -160, 260, 220]

def draw_bar(t, height):
    y_baseline = t.ycor()

    t.turtlesize(abs(height) / STAMP_UNIT, BAR_WIDTH / STAMP_UNIT, 2)  # size the bar
    t.left(90)
    t.forward(height / 2)  # move to the center of the bar
    t.right(90)
    t.stamp()

    t.left(90)
    t.forward(height / 2 + (-3 * FONTSIZE / 2 if height < 0 else 0))  # adjust font position when negative
    t.right(90)
    t.write(str(height), align="center", font=FONT)  # center text on bar

    t.forward(BAR_WIDTH + BAR_SPACING)  # move to the next bar center x-wise
    t.sety(y_baseline)  # return to our calculated baseline y-wise

wn = Screen()
wn.bgcolor("lightgreen")
wn.title("Barcharts FTW")

pen = Turtle(shape="square", visible=False)
pen.color("blue", "red")
pen.penup()

pen.goto(len(xs) * (BAR_SPACING + BAR_WIDTH) / -2, -max(xs) - min(xs))  # center graph based on data

for value in xs:
    draw_bar(pen, value)

wn.exitonclick()

另一个要研究的函数是 turtle.setworldcoordinates()。尽管对于大多数应用程序来说它可能很笨重,但我已经看到它在图形问题中使用得非常成功,因为它可以让您重新定义海龟的坐标系以满足您的数据需求。

注意 if height < 0 部分,它检查条形高度是否为负数。在这种情况下,海龟会向后移动 (tur_pen.forward(-15)),这样当它写入值时,文本不会与条重叠。

# Modified turtle pie chart II
# By Dave Zabel  3/29/2017 - 3/31/2017
# Import turtle and random modules
import turtle
import random

values = random.sample(range(-250, 250), 15)  # Initiate a list of 15 random values


def draw_bar(tur_pen, height):
    """Get turtle to draw one bar of height"""
    tur_pen.begin_fill()  # Begins color fill
    tur_pen.left(90)  # Starts a bar whose height is a value from the variable "values"
    tur_pen.forward(height)
    tur_pen.penup()  # Sequence checks for negative value so as to print value UNDER the line
    if height < 0:
        tur_pen.forward(-15)
    tur_pen.write('    ' + str(height))  # Prints the value of the bar height
    if height < 0:
        tur_pen.forward(15)
    tur_pen.pendown()  # Continues to complete one bar
    tur_pen.right(90)
    tur_pen.forward(40)
    tur_pen.right(90)
    tur_pen.forward(height)
    tur_pen.left(90)
    tur_pen.end_fill()  # Stops the fill process
    tur_pen.penup()  # Has the pen skip between bars
    tur_pen.forward(10)
    tur_pen.pendown()

bar_screen = turtle.Screen()  # Sets the attributes of the screen
bar_screen.title('Bar Graph')
bar_screen.bgcolor('light green')

bar = turtle.Turtle()  # Sets the attributes of the pen
bar.pensize(3)
bar.speed(5)
bar.penup()
bar.goto(-360, 0)
bar.pendown()
fill_color = ''  # Changes the fill color by height
for v in values:
    if v >= 200:
        fill_color = 'green'
    elif v >= 100 < 200:
        fill_color = 'yellow'
    elif v > 0 < 100:
        fill_color = 'gray'
    elif v < 0:
        fill_color = 'red'
    bar.color('blue', fill_color)
    draw_bar(bar, v)  # Starts the process

bar_screen.mainloop()  # Holds the screen open until the user closes it