【问题标题】:How to use both dashed-negatives defalut style + line colors in Matplotlib/Python?如何在 Matplotlib/Python 中同时使用虚线底片默认样式 + 线条颜色?
【发布时间】:2019-05-06 12:10:11
【问题描述】:

使用 Python/Matplotlib 绘制等高线图时,默认行为(对于 1 种颜色)是用虚线表示负值。这是我想要的功能。但是,如果我设置线条的颜色,它们都会被绘制成实心的。我想结合虚线底片和自定义颜色。

如何绘制彩色线条,并保持负划线样式?

下面,我复制(稍微修改一下),本教程的一个例子:https://www.oreilly.com/library/view/python-data-science/9781491912126/ch04.html

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

x = np.linspace(0, 5, 50)
y = np.linspace(0, 5, 40)
X, Y = np.meshgrid(x, y)
def f(x, y):
    return np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x)
Z = f(X, Y)

# Default: 1 color, negatives are dashed
plt.contour(X, Y, Z, colors='black')
plt.show()

# Set colormap: all lines are solid
plt.contour(X, Y, Z, cmap='RdBu')
plt.show()

# Set individual colors: all solid lines
plt.contour(X, Y, Z, colors=['b','b','b','r','r','r','r','r'])
plt.show()

默认值:否定用虚线表示。

通过颜色图设置颜色:所有颜色都变为纯色。

设置单个颜色:再次全部纯色。我希望这里的蓝线自动虚线,因为它们是负值。

【问题讨论】:

    标签: python matplotlib visualization contour


    【解决方案1】:

    不幸的是,负值的不同线型的特性并没有暴露给用户。它与线条是否使用单一颜色有关。这会切换属性monochrome,而后者又决定是否更改线型。

    因此,一个快速的技巧是将 monochrome 属性设置为 True 并重置线条样式。

    import matplotlib.pyplot as plt
    import numpy as np
    
    x = np.linspace(0, 5, 50)
    y = np.linspace(0, 5, 40)
    X, Y = np.meshgrid(x, y)
    def f(x, y):
        return np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x)
    Z = f(X, Y)
    
    
    cntr = plt.contour(X, Y, Z, cmap='RdBu')
    cntr.monochrome = True
    for col, ls in zip(cntr.collections, cntr._process_linestyles()):
        col.set_linestyle(ls)
    
    plt.show()
    

    由于这使用了私有._process_linestyles() 属性,因此不建议在生产代码中使用它;而是使用@WarrenWeckesser's answer 或下面的选项。

    这里我想指出设置linestyles 先验的选项,具体取决于级别:

    import matplotlib.pyplot as plt
    import matplotlib.ticker
    import numpy as np
    
    x = np.linspace(0, 5, 50)
    y = np.linspace(0, 5, 40)
    X, Y = np.meshgrid(x, y)
    def f(x, y):
        return np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x)
    Z = f(X, Y)
    
    
    loc = matplotlib.ticker.MaxNLocator(7)
    lvls = loc.tick_values(Z.min(), Z.max())
    cntr = plt.contour(X, Y, Z, levels=lvls, cmap='RdBu', 
                       linestyles=np.where(lvls >= 0, "-", "--"))
    
    plt.show()
    

    【讨论】:

      【解决方案2】:

      这是您可以做到的一种方法。 (matplotlib 大师可能会推荐一种更简单的方法。)

      此示例使用颜色图设置颜色,然后在创建等高线图后更改线型。虚线表示负轮廓,虚线表示 0,实线表示正。

      import matplotlib
      import matplotlib.pyplot as plt
      import numpy as np
      
      
      x = np.linspace(0, 5, 50)
      y = np.linspace(0, 5, 40)
      X, Y = np.meshgrid(x, y)
      def f(x, y):
          return np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x)
      Z = f(X, Y)
      
      # Contour with a specified colormap.
      result = plt.contour(X, Y, Z, cmap='RdBu')
      
      # Override the linestyles based on the levels.
      for line, lvl in zip(result.collections, result.levels):
          if lvl < 0:
              line.set_linestyle('--')
          elif lvl == 0:
              line.set_linestyle(':')
          else:
              # Optional; this is the default.
              line.set_linestyle('-')
      
      # Optional--this makes the 0 contour more visible with the
      # chosen colormap.
      ax = plt.gca()
      ax.set_facecolor('#d0d0d0')
      
      plt.show()
      

      结果如下:

      【讨论】:

      • 不幸的是,没有更简单的方法了。所以这绝对是一个不错的选择。
      • 很好的答案。谢谢。我接受了下一个答案,因为它解释了为什么会发生这种情况。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      • 2020-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多