【问题标题】:unique plot marker for each plot in matplotlibmatplotlib 中每个绘图的唯一绘图标记
【发布时间】:2012-10-16 23:56:58
【问题描述】:

我有一个循环,我在其中创建了一些图,并且我需要为每个图使用唯一的标记。我考虑创建一个返回随机符号的函数,并以这种方式在我的程序中使用它:

for i in xrange(len(y)):
    plt.plot(x, y [i], randomMarker())

但我认为这种方式不好。 我需要这个只是为了区分图例上的图,因为图不能与线相连,它们必须只是点集。

【问题讨论】:

  • 实际上是否需要每个标记都不同,或者您只是希望您的点不被一条线连接?
  • 我需要每个标记都不同,并且希望点不被线连接。

标签: python matplotlib


【解决方案1】:

itertools.cycle 将无限期地遍历列表或元组。这比为您随机选择标记的功能更可取。

Python 2.x

import itertools
marker = itertools.cycle((',', '+', '.', 'o', '*')) 
for n in y:
    plt.plot(x,n, marker = marker.next(), linestyle='')

Python 3.x

import itertools
marker = itertools.cycle((',', '+', '.', 'o', '*')) 
for n in y:
    plt.plot(x,n, marker = next(marker), linestyle='')

您可以使用它来生成这样的图(Python 2.x):

import numpy as np
import matplotlib.pyplot as plt
import itertools

x = np.linspace(0,2,10)
y = np.sin(x)

marker = itertools.cycle((',', '+', '.', 'o', '*')) 

fig = plt.figure()
ax = fig.add_subplot(111)

for q,p in zip(x,y):
    ax.plot(q,p, linestyle = '', marker=marker.next())
    
plt.show()

【讨论】:

  • +1'ed,因为这显示了一种很好的方式,它可以处理任意数量的图。同样的方法适用于颜色等。
  • +1 从来不知道 itertools.cycle。比我以前使用的半生不熟的 lambda/模数方案要好得多。
  • 对于那些使用 Python 3.x 的人来说,itertools.cycle.next 已更改为 next(itertools.cycle())。见stackoverflow.com/questions/5237611/itertools-cycle-next
【解决方案2】:

似乎还没有人提到用于循环属性的内置 pyplot 方法。所以这里是:

import numpy as np
import matplotlib.pyplot as plt
from cycler import cycler

x = np.linspace(0,3,20)
y = np.sin(x)

fig = plt.figure()
plt.gca().set_prop_cycle(marker=['o', '+', 'x', '*', '.', 'X']) # gca()=current axis

for q,p in zip(x,y):
    plt.plot(q,p, linestyle = '')

plt.show()

但是,这样会丢失颜色循环。您可以通过将颜色cycler 和标记cycler 对象相乘或相加来添加背景颜色,如下所示:

fig = plt.figure()

markercycle = cycler(marker=['o', '+', 'x', '*', '.', 'X'])
colorcycle = cycler(color=['blue', 'orange', 'green', 'magenta'])
# Or use the default color cycle:
# colorcycle = cycler(color=plt.rcParams['axes.prop_cycle'].by_key()['color'])

plt.gca().set_prop_cycle(colorcycle * markercycle) # gca()=current axis

for q,p in zip(x,y):
    plt.plot(q,p, linestyle = '')

plt.show()

在添加循环时,它们需要具有相同的长度,因此在这种情况下我们只使用markercycle的前四个元素:

plt.gca().set_prop_cycle(colorcycle + markercycle[:4]) # gca()=current axis

【讨论】:

  • 似乎不需要导入cycler 模块,而是可以使用plt.cycler 来实现相同的目的。例如。 mycyler = plt.cycler(marker=['o', '+'], color=['blue', 'orange']) 然后像往常一样在set_prop_cycle() 方法中使用它。
  • 值得一提的是,on 还可以“添加”循环器来获得一个循环器,它可以更改多个属性 aech time。
  • @PaulG。如果您愿意,请随意添加示例。
  • @PaulG。我的意思是编辑。在改进帖子时,我尝试遵循 Wikipedia 的“大胆”政策(只是自己进行改进而不是提出建议)。
  • @PaulG。那太棒了。这里不需要完美主义。 :-)
【解决方案3】:

您还可以通过元组使用标记生成,例如作为

import matplotlib.pyplot as plt
markers = [(i,j,0) for i in range(2,10) for j in range(1, 3)]
[plt.plot(i, 0, marker = markers[i], ms=10) for i in range(16)]

详情请见Matplotlib markers doc site

另外这个可以和上面提到的itertools.cycle循环结合

【讨论】:

  • 我喜欢这个答案,因为它允许您通过增加范围内的数量来增加标记的多样性。然而,它在 v2.0.2 中不起作用,因为第一个数字是三元组应该是整数:(numsides, style, angle)。我会更正:n = 16markers = [(2+i, 1+i%2, i/n*90.0) for i in range(1, n)]
【解决方案4】:

只需手动创建一个包含标记字符的数组并使用它,例如:

 markers=[',', '+', '-', '.', 'o', '*']

【讨论】:

  • 嗯,你究竟是如何“使用它”的?当我尝试ax.plot(t,s, marker=['s', 'o'], ...) 时,我得到TypeError: unhashable type: 'list'
  • 这类似于上面的想法,即在预定义的预定义列表上循环。我并不是建议它可以作为标志提供给 plot()。
【解决方案5】:
import matplotlib.pyplot as plt
fig = plt.figure()
markers=['^', 's', 'p', 'h', '8']
for i in range(5):
    plt.plot(x[i], y[i], c='green', marker=markers[i])
    plt.xlabel('X Label')
    plt.ylabel('Y Label') 
plt.show()

【讨论】:

  • 嗨,欢迎来到 Stack Overflow。在回答已经有很多答案的问题时,请务必添加一些额外的见解,说明为什么您提供的回复是实质性的,而不是简单地呼应原始发帖人已经审查过的内容。这在您提供的“纯代码”答案中尤其重要。
猜你喜欢
  • 2020-12-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-02
  • 2023-03-27
  • 2013-09-08
  • 1970-01-01
  • 2021-06-01
  • 1970-01-01
相关资源
最近更新 更多