Matplotlib 颜色图 – 为每个图形/线条/主题选择不同的颜色

问题描述 投票:0回答:4

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

这段代码运行良好。 Python 读取每个 .txt。文件并将 23 个单独的图形/线条绘制成一个图。 Python 在这里使用一些标准颜色,即每个图形自动以不同的颜色呈现。

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

问题:无论我使用互联网上的什么代码,所有图形/线条/主题总是收到相同的颜色(例如等离子颜色图中的第一个颜色或最后一个颜色)。

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

这是我的代码:

# 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()

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

screenshot

我正在运行 matplotlib

3.5.0
,并以
MacOSX
作为后端。

python matplotlib colormap
4个回答
8
投票

enter image description here

您想为颜色图实例提供一个在 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)))

4
投票

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

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, ....
。保留用于使用不同颜色绘制的代码按照上面的建议,你不会有任何问题。)


1
投票

我的CMasher有函数

take_cmap_colors()
https://cmasher.readthedocs.io/user/usage.html#take-colormap-colors),它是为了处理这种情况而编写的。 只需向它提供一个颜色图、颜色数量以及您想要的范围(可选),它就会返回一个从提供的颜色图统一获取的颜色列表(采用 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)。 您可能会在那里找到更适合您的情节的候选者。


0
投票

enter image description here

如果您想根据基于色彩图的配色方案为不同的艺术家(例如直线、弧线、矩形等)着色,那么

  1. 一个 Colormap 对象,你在
    cmap = plt.get_cmap('rainbow')
    中得到的那个是一个可调用的,
  2. 它将 0 到 1 之间的实数 映射到颜色图中的颜色。
因此,您会将要着色的每一位艺术家与一个实数

0 ≤ x ≤ 1

 相关联,并且在实例化该艺术家时,使用 
color=cmap(x)
 关键字参数。

在常见情况下,您必须为一系列

N

 对象着色,要充分使用颜色映射范围的颜色,配方是

for n in range(N): plt.plot(x, y[n], color=cmap(n/(N-1)))
最后,这是我的彩虹代码

import matplotlib.pyplot as plt from matplotlib.patches import Arc, Rectangle import numpy as np fig, ax = plt.subplots() plt.axis('off') # the "panorama" ax.add_patch(Rectangle((0,0), 1, 0.7, color='skyblue')) ax.fill_between(x, 0.2+0.05*x+0.1*np.sin((6-2*x)*x-0.6)**2, color="#206030") # no plot, my artist of choice are Arc's # https://matplotlib.org/stable/api/_as_gen/matplotlib.patches.Arc.html cmap = plt.get_cmap('rainbow') for (n, dr) in enumerate(np.linspace(0, 0.1, 256)): arc = Arc((+0.5, -0.1), 1.4+dr, 1.4+dr, theta1=0, theta2=180, color=cmap(n/256), alpha=0.9) ax.add_patch(arc) # tweak the x and y limits, fix the aspect ratio and have circula circles ax.set_xlim((0,1)), ax.set_ylim((0,0.7)), ax.set_aspect(1)
    
© www.soinside.com 2019 - 2024. All rights reserved.