本文笔者在学习过程中尝试用Canvas画折线图,有许多不足,不如用matplotlib来画,以下是完整代码。
import tkinter as tk
import math
Font_SIZE_D = 14
Font_SIZE_L = 14
CANVAS_WIDTH = 500
CANVAS_HEIGHT = 500
DOWN_UNIT = '年份'
LEFT_UNIT = '数量'
# 坐标值
down_v = ['2001', '2002', '2003', '2004', '2005', '2006']
left_v = ['100', '200', '300', '400', '500', '600']
root = tk.Tk()
root.geometry('500x500+300+200')
canvas = tk.Canvas(root, width=CANVAS_WIDTH, height=CANVAS_HEIGHT, bg='yellow')
canvas.pack()
start_x = int(CANVAS_WIDTH * 0.14)
start_y = int(CANVAS_HEIGHT * 0.9)
canvas.create_text(int(start_x * 0.8), int(start_y), text='0', font=('微软雅黑', 14, 'bold'))
down_b = []
left_b = []
# 算出每一格的长度
y = abs(start_y - int(start_y * 0.97))
x = int(start_x * 1.33)
# 取最小
if y >= x:
v = x
else:
v = y
# 4段
for i in range(1, len(down_v) + 1):
# 画横线
canvas.create_line(start_x * i, start_y, start_x * (i + 1), start_y, width=2)
canvas.create_line(start_x * (i + 1), start_y, start_x * (i + 1), int(start_y - v), width=2)
down_b.append(start_x * (i + 1))
# 写数据
canvas.create_text(start_x * (i + 1), int(start_y * 1.03), text=down_v[i - 1], font=('微软雅黑', Font_SIZE_D, 'bold'))
# 画竖线
canvas.create_line(start_x, start_y - start_x * (i - 1), start_x, start_y - start_x * i, width=2)
canvas.create_line(start_x, start_y - start_x * i, int(start_x + v), start_y - start_x * i, width=2)
left_b.append(start_y - start_x * i)
# 写数据
canvas.create_text(int(start_x * 0.6), start_y - start_x * i, text=left_v[i - 1],
font=('微软雅黑', Font_SIZE_L, 'bold'))
n = [down_b[0], left_b[0]]
# 真值(真实一格距离) 比 虚值(标注的值)
# 给的是标注的值 y
j = abs(int(start_x - n[0])) / 100
# x
h = abs(int(start_x - n[0])) / 1
s = [start_x + int(1 * h), start_y - int(75 * j), start_x + int(2 * h), start_y - int(125 * j), start_x + int(3 * h),
start_y - int(200 * j), start_x + int(4 * h), start_y - int(300 * j)]
canvas.create_line(*s, width=2, fill='blue')
canvas.create_line(*zip(down_b, left_b), width=2, fill='red')
# 下
canvas.create_line(start_x, start_y, start_x * 7, start_y, width=2)
# 画箭头
canvas.create_line(start_x * 7 - int(start_x * 0.15), start_y - int(start_y * 0.02), start_x * 7, start_y, width=2)
canvas.create_line(start_x * 7 - int(start_x * 0.15), start_y + int(start_y * 0.02), start_x * 7, start_y, width=2)
# 提示
canvas.create_text(start_x * 7 - int(start_x * 0.15), start_y + int(start_y * 0.07), text=LEFT_UNIT, width=2)
# 斜线长度
jian_size = math.pow(
(start_x * 7 - int(start_x * 0.15) - start_x * 7) ** 2 - (start_y - int(start_y * 0.02) - start_y) ** 2,
0.5)
deng = math.pow(2, 0.5) * 1.5
# 左
canvas.create_line(start_x, start_y, start_x, start_y - start_x * 6, width=2)
# 画箭头
canvas.create_line(start_x - deng - 5, int((start_y - start_x * 6) + deng + 5), start_x, start_y - start_x * 6,
width=2)
canvas.create_line(start_x + deng + 5, int((start_y - start_x * 6) + deng + 5), start_x, start_y - start_x * 6,
width=2)
# 提示
canvas.create_text(start_x - 15, start_y - start_x * 6 + 5, text=DOWN_UNIT, width=2)
root.mainloop()