增加 matplotlib 的颜色循环周期

15

有没有一种简单的方法来增加matplotlib颜色循环,而不必深入探究轴的内部?

在交互式绘图中,我经常使用的一个常见模式是:

import matplotlib.pyplot as plt

plt.figure()
plt.plot(x,y1)
plt.twinx()
plt.plot(x,y2)

使用 plt.twinx() 方法可以使 y1 和 y2 有不同的 y 轴刻度,但两个图都会使用默认颜色循环中的第一个颜色绘制,因此需要为每个图手动声明颜色。

必须有一种简洁的方法来指示第二个图增加颜色循环,而不是明确给出颜色。当然,对于两个图都设置 color='b'color='r' 非常容易,但如果使用自定义样式(如 ggplot),则需要从当前颜色循环中查找颜色代码,这对交互使用来说很麻烦。

3个回答

14

你可以称之为

ax2._get_lines.get_next_color()

为了推进颜色循环器的颜色,请使用以下代码。不幸的是,这会访问私有属性 ._get_lines ,因此它不是公共 API 的一部分,并且不能保证在未来的 matplotlib 版本中正常工作。

更安全但不太直接的推进颜色循环器的方法是绘制一个空图:

ax2.plot([], [])

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10)
y1 = np.random.randint(10, size=10)
y2 = np.random.randint(10, size=10)*100
fig, ax = plt.subplots()
ax.plot(x, y1, label='first')
ax2 = ax.twinx()
ax2._get_lines.get_next_color()
# ax2.plot([], [])
ax2.plot(x,y2, label='second')

handles1, labels1 = ax.get_legend_handles_labels()
handles2, labels2 = ax2.get_legend_handles_labels()
ax.legend(handles1+handles2, labels1+labels2, loc='best')  

plt.show()

这里输入图片描述


这解决了问题,但这只是我试图避免的冗长。通常明确使用轴对象来配置绘图可能是一个好主意,但我仍然经常使用写入gca()的plt.plot()快捷方式。 - Mike
实际上,我误读了答案。您似乎确实可以在一行中更改颜色。复杂的部分是使图例适用于双轴。 - Mike
希望能够有一个像plt.subplots()这样的工厂,可以在同一画布上生成多个轴,颜色和图例之类的元素直观地协作。 - Mike
我在matplotlib 1.5.1中没有看到ax._get_lines._get_next_color()方法。然而,空图解决方案非常简单且能够满足我的需求。 - Mike

12

与其他答案类似,但使用matplotlib颜色循环器:

import matplotlib.pyplot as plt
from itertools import cycle

prop_cycle = plt.rcParams['axes.prop_cycle']
colors = cycle(prop_cycle.by_key()['color'])
for data in my_data:
    ax.plot(data.x, data.y, color=next(colors))

2
+1 是因为它是无副作用的,避免了私有 _get_lines 访问,并清楚地表明了颜色值从哪里读取。 - bluenote10

6

在Pyplot中有多种颜色方案可供选择。您可以在matplotlib教程指定颜色中了解更多信息。

从这些文档中:

a "CN" color spec, i.e. 'C' followed by a number, which is an index into the
default property cycle (matplotlib.rcParams['axes.prop_cycle']); the indexing
is intended to occur at rendering time, and defaults to black if the cycle
does not include color.

您可以按照以下步骤循环使用颜色方案:
fig, ax = plt.subplots()

# Import Python cycling library
from itertools import cycle

# Create a colour code cycler e.g. 'C0', 'C1', etc.
colour_codes = map('C{}'.format, cycle(range(10)))

# Iterate over series, cycling coloour codes
for y in my_data:
    ax.plot(x, y, color=next(color_codes))

这可以通过直接循环遍历matplotlib.rcParams['axes.prop_cycle']来改进。

+1,因为不依赖于副作用。或许为了完整性,您的代码片段可以以 ax.plot(x, y, color=next(color_codes)) 结束。 - Bananach
颜色实际上来自哪里?Python 2 用户警告:map('C{}'.format, cycle(range(10))) 是一个无限循环。 - bluenote10

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接