Python 如何在 matplotlib 绘图循环中为标记和线条设置相同的颜色?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28779559/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set same color for markers and lines in a matplotlib plot loop?
提问by Tom Kurushingal
I have to plot multiple lines and markers with matplotlib by creating a loop and I have already set the axes color cycle in the matplolibrc param file. In each cycle of the loop a set of markers and lines are created (lines are created by a separate command). But the marker and line colors are different as per the axes color cycle. I want each time the loop is run the marker and lines to be of the same color of that cycle.
我必须通过创建循环来使用 matplotlib 绘制多条线和标记,并且我已经在 matplolibrc 参数文件中设置了轴颜色循环。在循环的每个循环中,都会创建一组标记和线条(线条由单独的命令创建)。但是标记和线条颜色根据轴颜色循环而不同。我希望每次循环运行时,标记和线条都与该循环具有相同的颜色。
I have included the reproducible code:
我已经包含了可重现的代码:
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()
Using this code the output I get is:
使用此代码,我得到的输出是:
I need the markers and lines plotted in their range to be of the same color. How can it be done in matplotlib?
我需要在其范围内绘制的标记和线条具有相同的颜色。如何在 matplotlib 中完成?
采纳答案by Joel
I present two ways. The first is probably cleaner: it loops through once, and within each loop, gets the next color, and then does two plotting commands with that color. In the second, it loops through and does all the markers and then it resets the colors and loops through again and does the lines.
我介绍两种方法。第一个可能更清晰:它循环一次,在每个循环中,获取下一种颜色,然后使用该颜色执行两个绘图命令。在第二个中,它循环并执行所有标记,然后重置颜色并再次循环并执行线条。
first method
第一种方法
Directly access the color cycle. If matplotlib 1.5 or later use color=next(ax._get_lines.prop_cycler)['color']
. Otherwise color=next(ax._get_lines.color_cycle)
:
直接访问颜色循环。如果 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')
Also, notice I changed your \textit{y}
to $y$
. Usually you actually want math fonts rather than italics.
另外,请注意我将您的更改\textit{y}
为$y$
. 通常你实际上想要数学字体而不是斜体。
second method
第二种方法
If you don't want to send a color in as an argument, you can reset the color cycle and go through the loop twice. Here I reset it before the first loop and then again before the second loop just to make sure it's starting from the same place.
如果您不想将颜色作为参数发送,您可以重置颜色循环并循环两次。在这里,我在第一个循环之前重置它,然后在第二个循环之前再次重置它,以确保它从同一个地方开始。
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')
回答by Jon Loveday
Note that in matplotlib 1.5 onwards, color_cycle has been replaced by prop_cycler. The first option then needs:
请注意,在 matplotlib 1.5 之后,color_cycle 已被 prop_cycler 取代。然后第一个选项需要:
color = next(ax._get_lines.prop_cycler)['color']
回答by Adriaan
Note that iter.next() was removed in Python 3.x as described in this question. If you run the examples in the accepted answer you will therefore receive AttributeError:
请注意,iter.next() 已在 Python 3.x 中删除,如本问题所述。如果您在接受的答案中运行示例,您将因此收到 AttributeError:
'itertools.cycle' object has no attribute 'next'
For both examples this can be solved by replacing:
对于这两个示例,这可以通过替换来解决:
marker=marker.next()
in plt.plot() with
在 plt.plot() 与
marker=next(marker)