【问题标题】:How to set same color for markers and lines in a matplotlib plot loop?如何在 matplotlib 绘图循环中为标记和线条设置相同的颜色?
【发布时间】:2015-05-01 00:29:19
【问题描述】:

我必须通过创建循环来使用 matplotlib 绘制多条线和标记,并且我已经在 matplolibrc 参数文件中设置了轴颜色循环。在循环的每个循环中,都会创建一组标记和线条(线条由单独的命令创建)。但是标记和线条颜色根据轴颜色周期而有所不同。我希望每次循环运行时,标记和线条的颜色与该循环的颜色相同。

我已经包含了可重现的代码:

import numpy as np
import itertools
import matplotlib.pyplot as plt
m = 5
n = 5
x = np.zeros(shape=(m, n))
plt.figure(figsize=(5.15, 5.15))
plt.clf()
plt.subplot(111)
marker = itertools.cycle(('o', 'v', '^', '<', '>', 's', '8', 'p'))
for i in range(1, n):
    x = np.dot(i, [1, 1.1, 1.2, 1.3])
    y = x ** 2
    plt.plot(x, y, linestyle='', markeredgecolor='none', marker=marker.next())
    plt.plot(x, y, linestyle='-')
plt.ylabel(r'\textit{y}', labelpad=6)
plt.xlabel(r'\textit{x}', labelpad=6)
plt.show()

使用此代码,我得到的输出是:

我需要在其范围内绘制的标记和线条具有相同的颜色。在matplotlib中怎么做?

【问题讨论】:

  • 为什么不plt.plot(x, y, marker=marker.next())

标签: python matplotlib


【解决方案1】:

我提出了两种方法。第一个可能更干净:它循环一次,在每个循环中,获取下一个颜色,然后使用该颜色执行两个绘图命令。在第二个中,它循环并完成所有标记,然后重置颜色并再次循环并完成线条。

第一种方法

直接访问颜色循环。如果 matplotlib 1.5 或更高版本使用color=next(ax._get_lines.prop_cycler)['color']。否则color=next(ax._get_lines.color_cycle):

import numpy as np
import itertools
import matplotlib.pyplot as plt
m = 5
n = 5
x = np.zeros(shape=(m, n))
plt.figure(figsize=(5.15, 5.15))
plt.clf()
plt.subplot(111)
marker = itertools.cycle(('o', 'v', '^', '<', '>', 's', '8', 'p'))

ax = plt.gca()
for i in range(1, n):
    x = np.dot(i, [1, 1.1, 1.2, 1.3])
    y = x ** 2
    #
    #for matplotlib before 1.5, use
    #color = next(ax._get_lines.color_cycle)
    #instead of next line (thanks to Jon Loveday for the update)
    #
    color = next(ax._get_lines.prop_cycler)['color']
    plt.plot(x, y, linestyle='', markeredgecolor='none', marker=marker.next(), color=color)
    plt.plot(x, y, linestyle='-', color = color)
plt.ylabel(r'$y$', labelpad=6)
plt.xlabel(r'$x$', labelpad=6)
plt.savefig('test2.png')

另外,请注意我将您的 \textit{y} 更改为 $y$。通常你实际上想要数学字体而不是斜体。

第二种方法

如果您不想将颜色作为参数发送,您可以重置颜色循环并循环两次。在这里,我在第一个循环之前重置它,然后在第二个循环之前再次重置它,以确保它从同一个地方开始。

import numpy as np
import itertools
import matplotlib.pyplot as plt
m = 5
n = 5
x = np.zeros(shape=(m, n))
plt.figure(figsize=(5.15, 5.15))
plt.clf()
plt.subplot(111)
marker = itertools.cycle(('o', 'v', '^', '<', '>', 's', '8', 'p'))

plt.gca().set_prop_cycle(None) #if matplotlib <1.5 use set_color_cycle
for i in range(1, n):
    x = np.dot(i, [1, 1.1, 1.2, 1.3])
    y = x ** 2
    plt.plot(x, y, linestyle='', markeredgecolor='none', marker=marker.next())
plt.gca().set_prop_cycle(None)
for i in range(1, n):
    x = np.dot(i, [1, 1.1, 1.2, 1.3])
    y = x ** 2
    plt.plot(x, y, linestyle='-')
plt.ylabel(r'$y$', labelpad=6)
plt.xlabel(r'$x$', labelpad=6)
plt.savefig('test.png')

【讨论】:

  • 如果 matplotlib 1.5 或更高版本,请使用 plt.gca().set_prop_cycle(None)。
  • 对于 Python 3.x 使用 marker=next(marker) 而不是 marker=marker.next(),请参阅下面的答案
  • 另外,代码中有一个小错字:plt.gca().set_prob_cycle(None) 应该是 p 而不是 b,所以:plt.gca().set_prop_cycle(None)
【解决方案2】:

请注意,从 matplotlib 1.5 开始,color_cycle 已被 prop_cycler 取代。那么第一个选项需要:

color = next(ax._get_lines.prop_cycler)['color']

【讨论】:

    【解决方案3】:

    请注意,在 Python 3.x 中删除了 iter.next(),如 this question 中所述。如果您在接受的答案中运行示例,您将收到 AttributeError:

    'itertools.cycle' object has no attribute 'next'
    

    对于这两个例子,这可以通过替换来解决:

    marker=marker.next()
    

    在 plt.plot() 中

    marker=next(marker)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-26
      • 2017-06-18
      • 2016-09-15
      • 2013-09-08
      • 1970-01-01
      • 1970-01-01
      • 2016-10-19
      • 1970-01-01
      相关资源
      最近更新 更多