Matplotlib Colormaps – 为每个 graph/line/subject 选择不同的颜色

Matplotlib Colormaps – Choosing a different color for each graph/line/subject

我创建了一个脚本来读取和绘制 .txt 文件及其内容 (numbers/values)。每个 .txt 文件位于不同的文件夹中。每个文件夹依次代表数据的一个主题。

这段代码工作正常。 Python 读取每个单独的 .txt。文件并将 23 个个体 graphs/lines 绘制成一个单独的图。 Python这里使用了一些标准颜色,即每张图自动以不同的颜色显示。

我想做的是:我不想使用 python 自动分配的标准颜色而不添加任何与颜色相关的代码,我想使用特定的颜色图(例如“ plasma") 来自 matplotlib.

问题:无论我使用来自互联网的什么代码,所有 graphs/lines/对象总是收到相同的颜色(例如等离子色图中的第一种颜色或最后一种颜色)。

如何指定代码,使每一行都从所选颜色图中获得一种不同的颜色?

这是我的代码:

# Initialize
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
from matplotlib.pyplot import cm

# Numpy.loadtxt – Loads data from a textfile. Scipy.signal.welch – Creation of the FFT/power-spectrum. f, Pxx_den creates the ideal frequencies/FFT (f, Welch = Power Spectrum or Power Spectral Density)
Subjects = ["Subject1", "Subject2", "Subject3", "Subject4", "Subject5", "Subject7", "Subject8", "Subject9", "Subject10", "Subject11", "Subject12", "Subject13",
            "Subject14", "Subject15", "Subject16", "Subject17", "Subject18", "Subject19", "Subject20", "Subject22", "Subject23", "Subject24", "Subject25"]

for Subject in Subjects:

    Subject = np.loadtxt("/volumes/SanDisk2/fmri/dataset/processed/extracted_timeseriespython/restingstate/{0}/TimeSeries.SPC.Core_ROI.{0}.txt".format(Subject), comments="#", delimiter=None,
                         converters=None, skiprows=0, usecols=0, unpack=False, ndmin=0, encoding=None, max_rows=None, like=None)

    f, Welch = signal.welch(Subject, fs=1.0, window="hann", nperseg=None, noverlap=None, nfft=1024, detrend="constant", return_onesided=True, scaling="density", axis=-1, average="mean")

    cmap = plt.get_cmap("inferno")
    slicedCM = cmap(np.linspace(0, 1, len(Subjects)))

    plt.plot(f, Welch, c=slicedCM[Subjects.index(Subject)]) 
    

# Grid labels
plt.title("Power Spectrum for all subjects", fontsize=12, fontweight="bold")
plt.xlabel("Log Frequency [Hz]", fontsize=11, fontweight="bold")
plt.ylabel("Log Power [Hz]", fontsize=11, fontweight="bold")

# Grid dimenions and style
plt.xlim([0.005, 0.2]) # x-axis range
plt.ylim([0, 100]) # y-axis range

plt.xticks(np.arange(0, 0.21, 0.025)) # x ticks range (start, end, step)
plt.yticks(np.arange(0, 101, 10)) # y ticks range (start, end, step)

plt.grid(True) # Show grid
plt.rc("axes", axisbelow=True) # Grid behind figures
plt.rc("grid", linestyle="-", color="black") # Grid look

# Show result
plt.show()

这是生成的屏幕截图,显示使用了标准颜色而不是所需的等离子颜色图:

我是 运行 matplotlib 3.5.0,后端是 MacOSX

实现您的目标的一种方法是分割颜色图,然后用其中一种生成的颜色绘制每条线。请参阅下面可以在适当位置集成到代码中的行。

import numpy as np
import matplotlib.pyplot as plt

# 1. Choose your desired colormap
cmap = plt.get_cmap('plasma')

# 2. Segmenting the whole range (from 0 to 1) of the color map into multiple segments
slicedCM = cmap(np.linspace(0, 1, len(Subjects))) 

# 3. Color the i-th line with the i-th color, i.e. slicedCM[i]
plt.plot(f, Welch, c=slicedCM[Subjects.index(Subject)]) 

(前两行可以放在开头,你可以用上面建议的第三行代码替换你代码中的线绘制曲线。)

或者,也许更简洁的方法是在 Subjects 的主循环中使用以下行:

cmap = plt.get_cmap('inferno')
plt.plot(f, Welch, c=cmap(Subjects.index(Subject)/len(Subjects))) 

(我在您的问题中看到,当您再次将文件加载到 Subject 时,您正在更改 Subject。只需使用另一个变量名称,例如 data = np.loadtxt...,然后 f, Welch = signal.welch(data, ....。保留上面建议的不同颜色绘图的代码,你不会有任何问题。)

您想为颜色图实例提供一个介于 0 和 1 之间的参数,这需要最少的计划,例如,

x = np.linspace(0,355/113, 101)
p = plt.get_cmap('plasma')
n = 23
for i in range(n):
    plt.plot(x, np.sin(x-i/2/n), color=p(i/(n-1)))

我的 CMasher 有函数 take_cmap_colors() (https://cmasher.readthedocs.io/user/usage.html#taking-colormap-colors),它就是为处理这种情况而编写的。 只需向它提供颜色图、颜色数量和您想要的可选范围,它就会 return 您从提供的颜色图中统一获取颜色列表(以 MPL 理解的格式)。

因此,在您的特定情况下,您可以这样做:

# Import CMasher
import cmasher as cmr

# Obtain colors from a colormap
colors = cmr.take_cmap_colors('inferno', len(Subjects))

# YOUR FOR-LOOP
for Subject, color in zip(Subjects, colors):

    Subject = np.loadtxt("/volumes/SanDisk2/fmri/dataset/processed/extracted_timeseriespython/restingstate/{0}/TimeSeries.SPC.Core_ROI.{0}.txt".format(Subject), comments="#", delimiter=None,
                         converters=None, skiprows=0, usecols=0, unpack=False, ndmin=0, encoding=None, max_rows=None, like=None)

    f, Welch = signal.welch(Subject, fs=1.0, window="hann", nperseg=None, noverlap=None, nfft=1024, detrend="constant", return_onesided=True, scaling="density", axis=-1, average="mean")

    plt.plot(f, Welch, c=color)

您可以为函数提供 MPL 中任何已注册颜色图的名称,或者如果您使用自定义、未注册的颜色图,则可以使用 Colormap 对象。

另请查看 CMasher 为您提供的颜色图 (https://cmasher.readthedocs.io/user/introduction.html)。 您可能会在那里找到更适合您的阴谋的候选人。