我有两个嵌套的列表,它们具有要在同一图中绘制的x轴和y轴的值。
通过for循环遍历值可以生成预期的图,但是对于较大的列表而言则相对较慢。因此,我一直在寻找相同的功能,但没有循环,我认为matplotlib可以处理,但情节并非我所期望的。
代码如下:
import matplotlib.pyplot as plt
xs = [[11, 20], [31, 31], [32, 33]]
ys = [[1, 10], [3, 4], [6, 10]]
有了循环,这个数字就可以了:
fig, ax = plt.subplots()
for i, x in enumerate(xs):
ax.plot(x, ys[i])
plt.show()
但是仅将列表提供给matplotlib并不会生成相同的图:
fig, ax = plt.subplots()
ax.plot(xs, ys)
plt.show()
在没有循环的情况下执行此操作的正确方法是什么?
答案 0 :(得分:3)
当线段列表很大时,可以使用LineCollection
而不是多次调用plt.plot
来提高性能:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.collections as mcoll
xs = [[11, 20], [31, 31], [32, 33]]
ys = [[1, 10], [3, 4], [6, 10]]
fig, ax = plt.subplots()
# https://matplotlib.org/gallery/color/color_cycle_default.html
prop_cycle = plt.rcParams['axes.prop_cycle']
colors = prop_cycle.by_key()['color']
segments = np.array(list(zip(xs, ys))).swapaxes(1,2)
line_segments = mcoll.LineCollection(segments, colors=colors)
ax.add_collection(line_segments)
ax.set(xlim=(10,34), ylim=(0,11))
plt.show()
以下是一些其他使用LineCollection
的示例:
LineCollection
期望第一个参数为[(pt0, pt1), (pt2, pt3), (pt4, pt5), ...]
形式的序列,其中每个pt
的形式为(x-coord, y-coord)
。
Matplotlib然后将LineCollection
渲染为线段
pt0 --> pt1
pt2 --> pt3
pt4 --> pt5
etc.
在上面的代码中使用swapaxes
的原因是因为zip(xs, ys)
创建((x0, x1), (y0, y1))
形式的对,而
LineCollection
希望点对的形式为((x0, y0), (x1, y1))
。