【问题标题】:Increment matplotlib color cycle增加 matplotlib 颜色循环
【发布时间】:2016-06-17 21:10:38
【问题描述】:

有没有一种简单的方法来增加 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 这样的自定义样式时,您需要从当前颜色循环中查找颜色代码,这对于交互使用来说很麻烦。

【问题讨论】:

    标签: python matplotlib jupyter-notebook


    【解决方案1】:

    与其他答案类似,但使用 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))
    

    【讨论】:

    • +1 因为没有副作用,避免了私人_get_lines 访问,并且非常清楚从哪里读​​取颜色值。
    【解决方案2】:

    你可以打电话

    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() 快捷方式。
    • 其实我看错了答案。您似乎确实在一行中更改了颜色。复杂的部分是让图例适用于双轴。
    • 如果有一个像 plt.subplots() 这样的工厂,它可以在同一个画布中生成多个轴,颜色和图例等内容可以直观地协作。
    • 我在 matplotlib 1.5.1 中没有看到 ax._get_lines._get_next_color() 方法。空绘图解决方案非常简单,可以满足我的需要。
    【解决方案3】:

    Pyplot 中有多种配色方案可用。您可以在 matplotlib 教程Specifying Colors 上阅读更多内容。

    来自这些文档:

    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 因为不依赖副作用。也许为了完整起见,您的 sn-p 可能以 ax.plot(x,y,color=next(color_codes)) 结尾
    • 颜色实际上来自哪里? Python 2 用户警告:map('C{}'.format, cycle(range(10))) 是一个无限循环。
    猜你喜欢
    • 2015-08-12
    • 2014-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-10
    • 2014-08-03
    相关资源
    最近更新 更多