python 如何在嵌套的for循环中正确编写matplotlib的色彩Map表索引?

ia2d9nvy  于 2022-12-10  发布在  Python
关注(0)|答案(1)|浏览(121)

**用可重现的代码更新:**我的数据以数值的形式存储在一个名为dict_data的嵌套字典中。该字典包括两个变量(嵌套字典),分别名为plesampen。这两个变量都附加了三个rois(数据列表)。

此外,在嵌套的for循环for variable in variables: for i in range(3):中,字典的数据被分别重新存储到plesampennumpy array中。接下来,我对numpy数组数据应用快速Z变换,并将结果保存到另一个新的numpy数组data_array_z中。

**下面是我的目标:**我想绘制变量plesampen的散点图,包括它们的三个rois(参见列表rois和字典dict_data)。另外,我想绘制三个rois中数据点的线性回归线。最后的图像显示了使用此代码可重现的结果。到目前为止,所有这些都有效。
**问题:**我想将matplotlib的colormap应用于变量的散点及其回归线。我不知道如何编写c=color=命令,以便matplotlib使用指定颜色Map表(如tab20c_r)中的单独颜色绘制每个新点和回归线。

当前我收到以下错误。AttributeError: 'numpy.ndarray' object has no attribute 'index'
下面是我的完整代码概述:

import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
from scipy import stats

# Data
rois = ["interoception", "exteroception", "cognitive"]
variables = ["ple", "sampen"]

dict_data = {
    "ple":
    {"interoception": [-1.10037122285797, -1.12865588460383, -0.703950853686781],
     "exteroception": [-1.17398360636007, -1.3990001171012, -1.04528124479161],
     "cognitive": [-1.41360171989828, -1.40283540165903, -0.97942989571082]},
     "sampen":
    {"interoception": [0.949609993391806, 0.855956231042865, 0.960562761361569],
     "exteroception": [0.910728054043017, 0.800209085753256, 0.884463613744541],
     "cognitive": [0.832925242590743, 0.782835997734383, 0.899277318610028]},
    }

# Linear regression for each subject and variable across the three regions
x_pos_1 = np.array([0, 1, 2])
x_pos_2 = np.array([3, 4, 5])

for variable in variables:
    for i in range(3):
        data_array = np.array([
            dict_data[variable]["interoception"][i],
            dict_data[variable]["exteroception"][i],
            dict_data[variable]["cognitive"][i]
            ])

        # Z normalization
        data_array_z = []
        for i in data_array:
            z = (i - np.mean(data_array)) / np.std(data_array)
            data_array_z.append(z)
        
        # Plot
        cmap = plt.get_cmap("tab20c_r")
        segment_cmap = cmap(np.linspace(0, 1, len(data_array_z)))

        if variable == "ple":
            reg = sp.stats.linregress(x_pos_1, data_array_z)
            plt.scatter(x_pos_1, data_array_z, color=segment_cmap[data_array.index(i)])
            plt.plot(x_pos_1, reg[1] + reg[0]*x_pos_1,
                     linestyle="-", linewidth=1, color=segment_cmap[data_array.index(i)],
                zorder=2)

        elif variable == "sampen":
            reg = sp.stats.linregress(x_pos_2, data_array_z)
            plt.scatter(x_pos_2, data_array_z)
            plt.plot(x_pos_2, reg[1] + reg[0]*x_pos_2,
                     linestyle="-", linewidth=1, zorder=2)
plt.show()

这是从第一个图中删除代码线color=segment_cmap[data_array.index(i)]时的结果,因此matplotlib仅采用其默认色彩Map表。

hmtdttj4

hmtdttj41#

您的代码有两个问题。
1.在内部循环中重用名称i,当内部循环完成时,i现在是一个浮点数,而不是数据列的索引。
1.您有从定性颜色贴图中选择颜色的想法,但默认情况下Matplotlib使用定性颜色贴图中的颜色,您只需使用它们。
Re ①,我更改了内部循环变量的名称,Re ②我使用循环器对象来遍历tab20c_r颜色Map表中的颜色-根据您的代码,我使用了3种颜色,但这些颜色在图中重复,这是您想要的吗?
此外,我还添加了一个图例。

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import linregress
from cycler import cycler

# Data
rois = ["interoception", "exteroception", "cognitive"]
variables = ["ple", "sampen"]

dict_data = {
    "ple":
    {"interoception": [-1.10037122285797, -1.12865588460383, -0.703950853686781],
     "exteroception": [-1.17398360636007, -1.3990001171012, -1.04528124479161],
     "cognitive": [-1.41360171989828, -1.40283540165903, -0.97942989571082]},
     "sampen":
    {"interoception": [0.949609993391806, 0.855956231042865, 0.960562761361569],
     "exteroception": [0.910728054043017, 0.800209085753256, 0.884463613744541],
     "cognitive": [0.832925242590743, 0.782835997734383, 0.899277318610028]},
    }

# Linear regression for each subject and variable across the three regions
x_pos_1 = np.array([0, 1, 2])
x_pos_2 = np.array([3, 4, 5])

plt.gca().set_prop_cycle(
    cycler(color=plt.get_cmap("tab20c_r")(np.linspace(0, 1, 3))))

for variable in variables:
    for i in range(3):

        data_array = np.array([
            dict_data[variable]["interoception"][i],
            dict_data[variable]["exteroception"][i],
            dict_data[variable]["cognitive"][i]
            ])

        # Z normalization
        data_array_z = []
        for y in data_array:
            z = (y - np.mean(data_array)) / np.std(data_array)
            data_array_z.append(z)
        
        # Plot
        if variable == "ple" or variable == "acw":
            reg = linregress(x_pos_1, data_array_z)
            print(i)
            plt.scatter(x_pos_1, data_array_z, **color, label="%s, %s"%(variable, i+1))
            plt.plot(x_pos_1, reg[1] + reg[0]*x_pos_1,
                     linestyle="-", linewidth=1)

        elif variable == "sampen":
            reg = linregress(x_pos_2, data_array_z)
            plt.scatter(x_pos_2, data_array_z, label="%s, %s"%(variable, i+1))
            plt.plot(x_pos_2, reg[1] + reg[0]*x_pos_2,
                     linestyle="-", linewidth=1, zorder=2)
plt.legend()
plt.show()

相关问题