使用 matplotlib 绘制给定笛卡尔坐标的路径
Using matplotlib to draw a path given cartesian coordinates
我是 matplotlib 和 numpy 的新手,我正在尝试将一些数组数据绘制成如下所示:
但目前看起来像这样:
我的代码非常基础,但基本上上图是我希望能够做到的。我不太关心绘制网格线,但情节应该成比例。我看过 mathplotlib 网站上的一些例子,但找不到足够相似的东西。
我想知道是不是 pyplot 程序不正确或者我的数组格式不正确?
import numpy as np
from matplotlib import pyplot as plt
data = [(2, 2), (3, 2), (4, 1), (4, 0), (3, 0), (3, 1), (4, 2),
(4, 3), (4, 4), (3, 3), (3, 4), (2, 4), (2, 3), (1, 4),
(0, 4), (0, 3), (1, 3), (0, 2), (1, 2), (0, 1), (0, 0),
(1, 0), (1, 1), (2, 0), (2, 1)]
data = np.asarray(data)
print(data)
plt.ylim(0, 4)
plt.xlim(0, 4)
plt.axis([0, 4, 0, 4])
plt.plot(data)
plt.show()
尝试
plt.plot(*data.transpose())
而不是
plt.plot(data)
plt.plot
函数采用 2 个数组,一个包含所有 x-values,一个包含所有 y-values。您不能将 x 和 y 值的混合传递给它。 transpose 方法将对值重新排序,以便所有 x 值在一起并且所有 y 值在一起并且星号 *
运算符会将这些数组解压缩到两个单独的函数参数中。
您可以尝试这样的操作:
import numpy as np
from matplotlib import pyplot as plt
data = [(2, 2), (3, 2), (4, 1), (4, 0), (3, 0), (3, 1), (4, 2),
(4, 3), (4, 4), (3, 3), (3, 4), (2, 4), (2, 3), (1, 4),
(0, 4), (0, 3), (1, 3), (0, 2), (1, 2), (0, 1), (0, 0),
(1, 0), (1, 1), (2, 0), (2, 1)]
for i in range(len(data) -1):
x1 = data[i][0]
y1 = data[i][1]
x2 = data[i+1][0]
y2 = data[i+1][1]
plt.plot([x1, x2], [y1, y2], c='blue')
plt.scatter(x1, y1, c='blue')
plt.show()
您需要像这样将 x 和 y 分量解压缩到数组中:
plt.plot([p[0] for p in data], [p[1] for p in data], 'o-')
使用格式样式"o-"
:“o”表示符号标记,“-”表示实线。
要同时格式化 x/y 刻度,这里是完整代码:
from matplotlib import pyplot as plt
data = [(2, 2), (3, 2), (4, 1), (4, 0), (3, 0), (3, 1), (4, 2),
(4, 3), (4, 4), (3, 3), (3, 4), (2, 4), (2, 3), (1, 4),
(0, 4), (0, 3), (1, 3), (0, 2), (1, 2), (0, 1), (0, 0),
(1, 0), (1, 1), (2, 0), (2, 1)]
x = [p[0] for p in data]
y = [p[1] for p in data]
_, ax = plt.subplots()
ax.set_xticks(range(5))
ax.set_yticks(range(5))
ax.plot(x, y, 'o-', color='blue')
plt.grid() # add grid lines
plt.show()
输出:
为了完成其他答案,这里是我在合理的时间内得到的最接近您所需输出的答案:
import numpy as np
from matplotlib import pyplot as plt
data = [(2, 2), (3, 2), (4, 1), (4, 0), (3, 0), (3, 1), (4, 2),
(4, 3), (4, 4), (3, 3), (3, 4), (2, 4), (2, 3), (1, 4),
(0, 4), (0, 3), (1, 3), (0, 2), (1, 2), (0, 1), (0, 0),
(1, 0), (1, 1), (2, 0), (2, 1)]
data = np.asarray(data)
print(data)
# make axis equal and turn them off
plt.axis('equal')
plt.axis('off')
for i in range(5):
# horizontal and vertical background lines
plt.plot([i,i], [0,4], linewidth=0.5, color='black')
plt.plot([0,4], [i,i], linewidth=0.5, color='black')
plt.plot(data[:,0], data[:,1], 'b') # line segments
plt.scatter(data[:,0], data[:,1], c='b') # markers
plt.show()
输出:
编辑
从 this question 开始,您可以通过 plt.annotate
在每个标记处添加数字。只需在 plt.scatter
之后添加:
offset = np.array([0.1, 0.1])
for i in range(data.shape[0]):
# For each marker
plt.annotate(str(i+1), data[i]+offset)
输出:
编辑#2:
作为奖励,这是我尽可能接近参考图的尝试:
import numpy as np
from matplotlib import pyplot as plt
data = [(2, 2), (3, 2), (4, 1), (4, 0), (3, 0), (3, 1), (4, 2),
(4, 3), (4, 4), (3, 3), (3, 4), (2, 4), (2, 3), (1, 4),
(0, 4), (0, 3), (1, 3), (0, 2), (1, 2), (0, 1), (0, 0),
(1, 0), (1, 1), (2, 0), (2, 1)]
data = np.asarray(data)
print(data)
# make axis equal and turn them off
plt.axis('equal')
plt.axis('off')
for i in range(5):
# horizontal and vertical background lines
plt.plot([i,i], [0,4], linewidth=1.5, color='#b3b3b3', zorder=1)
plt.plot([0,4], [i,i], linewidth=1.5, color='#b3b3b3', zorder=1)
plt.plot(data[:,0], data[:,1], '#274b8b', linewidth=2.5, zorder=2) # line segments
plt.scatter(data[np.arange(len(data))!=7,0], data[np.arange(len(data))!=7,1], s=60, c='#4472c4', edgecolors='#2e569c', zorder=3) # markers
# marker for point 7 is not plotted in reference figure
# Individual points numbers, not in reference figure so commented
# offset = np.array([0.1, 0.1])
# for i in range(data.shape[0]):
# # For each marker
# plt.annotate(str(i+1), data[i]+offset)
for i in range(5):
plt.annotate(str(i), [i-0.05, -0.25]) # X axis numbers
plt.annotate(str(i), [-0.2, i-0.07]) # Y axis numbers
plt.show()
我是 matplotlib 和 numpy 的新手,我正在尝试将一些数组数据绘制成如下所示:
但目前看起来像这样:
我的代码非常基础,但基本上上图是我希望能够做到的。我不太关心绘制网格线,但情节应该成比例。我看过 mathplotlib 网站上的一些例子,但找不到足够相似的东西。 我想知道是不是 pyplot 程序不正确或者我的数组格式不正确?
import numpy as np
from matplotlib import pyplot as plt
data = [(2, 2), (3, 2), (4, 1), (4, 0), (3, 0), (3, 1), (4, 2),
(4, 3), (4, 4), (3, 3), (3, 4), (2, 4), (2, 3), (1, 4),
(0, 4), (0, 3), (1, 3), (0, 2), (1, 2), (0, 1), (0, 0),
(1, 0), (1, 1), (2, 0), (2, 1)]
data = np.asarray(data)
print(data)
plt.ylim(0, 4)
plt.xlim(0, 4)
plt.axis([0, 4, 0, 4])
plt.plot(data)
plt.show()
尝试
plt.plot(*data.transpose())
而不是
plt.plot(data)
plt.plot
函数采用 2 个数组,一个包含所有 x-values,一个包含所有 y-values。您不能将 x 和 y 值的混合传递给它。 transpose 方法将对值重新排序,以便所有 x 值在一起并且所有 y 值在一起并且星号 *
运算符会将这些数组解压缩到两个单独的函数参数中。
您可以尝试这样的操作:
import numpy as np
from matplotlib import pyplot as plt
data = [(2, 2), (3, 2), (4, 1), (4, 0), (3, 0), (3, 1), (4, 2),
(4, 3), (4, 4), (3, 3), (3, 4), (2, 4), (2, 3), (1, 4),
(0, 4), (0, 3), (1, 3), (0, 2), (1, 2), (0, 1), (0, 0),
(1, 0), (1, 1), (2, 0), (2, 1)]
for i in range(len(data) -1):
x1 = data[i][0]
y1 = data[i][1]
x2 = data[i+1][0]
y2 = data[i+1][1]
plt.plot([x1, x2], [y1, y2], c='blue')
plt.scatter(x1, y1, c='blue')
plt.show()
您需要像这样将 x 和 y 分量解压缩到数组中:
plt.plot([p[0] for p in data], [p[1] for p in data], 'o-')
使用格式样式"o-"
:“o”表示符号标记,“-”表示实线。
要同时格式化 x/y 刻度,这里是完整代码:
from matplotlib import pyplot as plt
data = [(2, 2), (3, 2), (4, 1), (4, 0), (3, 0), (3, 1), (4, 2),
(4, 3), (4, 4), (3, 3), (3, 4), (2, 4), (2, 3), (1, 4),
(0, 4), (0, 3), (1, 3), (0, 2), (1, 2), (0, 1), (0, 0),
(1, 0), (1, 1), (2, 0), (2, 1)]
x = [p[0] for p in data]
y = [p[1] for p in data]
_, ax = plt.subplots()
ax.set_xticks(range(5))
ax.set_yticks(range(5))
ax.plot(x, y, 'o-', color='blue')
plt.grid() # add grid lines
plt.show()
输出:
为了完成其他答案,这里是我在合理的时间内得到的最接近您所需输出的答案:
import numpy as np
from matplotlib import pyplot as plt
data = [(2, 2), (3, 2), (4, 1), (4, 0), (3, 0), (3, 1), (4, 2),
(4, 3), (4, 4), (3, 3), (3, 4), (2, 4), (2, 3), (1, 4),
(0, 4), (0, 3), (1, 3), (0, 2), (1, 2), (0, 1), (0, 0),
(1, 0), (1, 1), (2, 0), (2, 1)]
data = np.asarray(data)
print(data)
# make axis equal and turn them off
plt.axis('equal')
plt.axis('off')
for i in range(5):
# horizontal and vertical background lines
plt.plot([i,i], [0,4], linewidth=0.5, color='black')
plt.plot([0,4], [i,i], linewidth=0.5, color='black')
plt.plot(data[:,0], data[:,1], 'b') # line segments
plt.scatter(data[:,0], data[:,1], c='b') # markers
plt.show()
输出:
编辑
从 this question 开始,您可以通过 plt.annotate
在每个标记处添加数字。只需在 plt.scatter
之后添加:
offset = np.array([0.1, 0.1])
for i in range(data.shape[0]):
# For each marker
plt.annotate(str(i+1), data[i]+offset)
输出:
编辑#2:
作为奖励,这是我尽可能接近参考图的尝试:
import numpy as np
from matplotlib import pyplot as plt
data = [(2, 2), (3, 2), (4, 1), (4, 0), (3, 0), (3, 1), (4, 2),
(4, 3), (4, 4), (3, 3), (3, 4), (2, 4), (2, 3), (1, 4),
(0, 4), (0, 3), (1, 3), (0, 2), (1, 2), (0, 1), (0, 0),
(1, 0), (1, 1), (2, 0), (2, 1)]
data = np.asarray(data)
print(data)
# make axis equal and turn them off
plt.axis('equal')
plt.axis('off')
for i in range(5):
# horizontal and vertical background lines
plt.plot([i,i], [0,4], linewidth=1.5, color='#b3b3b3', zorder=1)
plt.plot([0,4], [i,i], linewidth=1.5, color='#b3b3b3', zorder=1)
plt.plot(data[:,0], data[:,1], '#274b8b', linewidth=2.5, zorder=2) # line segments
plt.scatter(data[np.arange(len(data))!=7,0], data[np.arange(len(data))!=7,1], s=60, c='#4472c4', edgecolors='#2e569c', zorder=3) # markers
# marker for point 7 is not plotted in reference figure
# Individual points numbers, not in reference figure so commented
# offset = np.array([0.1, 0.1])
# for i in range(data.shape[0]):
# # For each marker
# plt.annotate(str(i+1), data[i]+offset)
for i in range(5):
plt.annotate(str(i), [i-0.05, -0.25]) # X axis numbers
plt.annotate(str(i), [-0.2, i-0.07]) # Y axis numbers
plt.show()