在 Matplotlib 中用 90 度角的线绘制序列
Plotting a sequence with lines at 90 degree angles in Matplotlib
我想绘制 Recamán 的序列 (more info on the sequence here),先绘制一条长度等于第一个元素的线,然后垂直绘制一条线,并从第一条线的末尾开始,长度等于第二个元素,等等。
我的代码如下:
import matplotlib.pyplot as plt
import numpy as np
import math
def pal(point, angle, length): #this plots a line starting at (point), with
# unpack the first point #certain angle and length
x, y = point
# find the end point
endy = y + length * math.sin(math.radians(angle)) #calculates change in y and adds to starting value
endx = x + length * math.cos(math.radians(angle)) #calculates change in x and adds to starting value
# plots the line with the starting coordinate and the calculated end coordinate
ax.plot([x, endx], [y,endy])
# end of plot function code
#this is where the elements of the recaman sequence get calculated and added to an array
recaman = []
crn = 0
elements = 100
for i in range(1, elements):
recaman.append(crn)
if (crn - i in recaman) or (crn - i < 0):
crn = crn + i
else:
crn = crn - i
#end of recaman calculation
x = 0
y = 0
angle = 0
length = 0
fig, ax = plt.subplots() #creating figure
for i in range(1, elements):
length = recaman[i-1] #obtain length of next line
pal((x, y), angle, length) #((starting coordinate),
# angle of line relative to x-axis, length of line)
if angle == 270: #resets angle to 0 to complete one full rotation
angle = 0
else:
angle = angle + 90 #adds 90 to angle to draw perpendicular line
y = y + length * math.sin(math.radians(angle)) #moves the new starting point to the old end point
x = x + length * math.cos(math.radians(angle))
plt.show()
预期结果如下所示:
实际结果是,好吧,不是这样的:
我已经多次深入研究我的代码,试图找出我做错了什么,但对我来说一切都很好。需要比我眼光更敏锐的人的帮助。
只需要重新排序一些语句。在更新角度之前拉出 x 和 y 更新方程。
y = y + length * math.sin(math.radians(angle)) # moves the new starting point to the old end point
x = x + length * math.cos(math.radians(angle))
if angle == 270: # resets angle to 0 to complete one full rotation
angle = 0
else:
angle = angle + 90 # adds 90 to angle to draw perpendicular line
稍微不同的方法是将方向硬编码到循环器中,循环器返回北-西-南-东-北等方向。允许我们直接将绘图保留在计算序列的循环中。为了好玩和娱乐,我让它也可以交互显示剧情,这样我们就可以看到序列的发展。
import matplotlib.pyplot as plt
from itertools import cycle
#this iterator cycles through the four directions
NWSE = cycle([[0, 1], [-1, 0], [0, -1], [1, 0]])
fig, ax = plt.subplots()
plt.ion()
plt.show()
recaman = []
crn = 0
elements = 100
#xy keeps track of the coordinates to plot as [[x1, x2], [y1, y2]]
xy= [[0, 0], [0, 0]]
for i in range(1, elements):
recaman.append(crn)
if (crn - i in recaman) or (crn - i < 0):
crn = crn + i
else:
crn = crn - i
#plotting
xy = [[coordxy[1], coordxy[1] + direction * crn] for coordxy, direction in zip(xy, next(NWSE))]
plt.plot(*xy)
#here you can speed it up with smaller values
plt.pause(0.2)
input("press key")
plt.close()
不出所料,输出是相同的:
我想绘制 Recamán 的序列 (more info on the sequence here),先绘制一条长度等于第一个元素的线,然后垂直绘制一条线,并从第一条线的末尾开始,长度等于第二个元素,等等。
我的代码如下:
import matplotlib.pyplot as plt
import numpy as np
import math
def pal(point, angle, length): #this plots a line starting at (point), with
# unpack the first point #certain angle and length
x, y = point
# find the end point
endy = y + length * math.sin(math.radians(angle)) #calculates change in y and adds to starting value
endx = x + length * math.cos(math.radians(angle)) #calculates change in x and adds to starting value
# plots the line with the starting coordinate and the calculated end coordinate
ax.plot([x, endx], [y,endy])
# end of plot function code
#this is where the elements of the recaman sequence get calculated and added to an array
recaman = []
crn = 0
elements = 100
for i in range(1, elements):
recaman.append(crn)
if (crn - i in recaman) or (crn - i < 0):
crn = crn + i
else:
crn = crn - i
#end of recaman calculation
x = 0
y = 0
angle = 0
length = 0
fig, ax = plt.subplots() #creating figure
for i in range(1, elements):
length = recaman[i-1] #obtain length of next line
pal((x, y), angle, length) #((starting coordinate),
# angle of line relative to x-axis, length of line)
if angle == 270: #resets angle to 0 to complete one full rotation
angle = 0
else:
angle = angle + 90 #adds 90 to angle to draw perpendicular line
y = y + length * math.sin(math.radians(angle)) #moves the new starting point to the old end point
x = x + length * math.cos(math.radians(angle))
plt.show()
预期结果如下所示:
实际结果是,好吧,不是这样的:
我已经多次深入研究我的代码,试图找出我做错了什么,但对我来说一切都很好。需要比我眼光更敏锐的人的帮助。
只需要重新排序一些语句。在更新角度之前拉出 x 和 y 更新方程。
y = y + length * math.sin(math.radians(angle)) # moves the new starting point to the old end point
x = x + length * math.cos(math.radians(angle))
if angle == 270: # resets angle to 0 to complete one full rotation
angle = 0
else:
angle = angle + 90 # adds 90 to angle to draw perpendicular line
稍微不同的方法是将方向硬编码到循环器中,循环器返回北-西-南-东-北等方向。允许我们直接将绘图保留在计算序列的循环中。为了好玩和娱乐,我让它也可以交互显示剧情,这样我们就可以看到序列的发展。
import matplotlib.pyplot as plt
from itertools import cycle
#this iterator cycles through the four directions
NWSE = cycle([[0, 1], [-1, 0], [0, -1], [1, 0]])
fig, ax = plt.subplots()
plt.ion()
plt.show()
recaman = []
crn = 0
elements = 100
#xy keeps track of the coordinates to plot as [[x1, x2], [y1, y2]]
xy= [[0, 0], [0, 0]]
for i in range(1, elements):
recaman.append(crn)
if (crn - i in recaman) or (crn - i < 0):
crn = crn + i
else:
crn = crn - i
#plotting
xy = [[coordxy[1], coordxy[1] + direction * crn] for coordxy, direction in zip(xy, next(NWSE))]
plt.plot(*xy)
#here you can speed it up with smaller values
plt.pause(0.2)
input("press key")
plt.close()
不出所料,输出是相同的: