Можно ли получить график из панды, в который включены данные, отсутствующие в Heatmap с особым цветом? - PullRequest
0 голосов
/ 13 января 2019

Мне было интересно, смогу ли я получить все графики столбцов в кадре данных panda в одном окне с помощью карты тепла в 24x20 самодельном квадрате матрицы-модели, который я разработал для отображения каждых 480 значений каждого столбца (что означает 1-цикл ) сопоставляя их внутри него через все циклы. Сложность в том, что я хочу показать недостающие данные, используя особый цвет, который находится вне цветовой гаммы карты цветов cmap ='coolwarm'

Я уже пытался с помощью df = df.replace([np.inf, -np.inf], np.nan) убедиться, что все inf преобразованы в nan, а затем с помощью df = df.replace(0,np.nan) до sns.heatmap(df, vmin=-1, vmax=+1, cmap ='coolwarm' я могу распознать пропущенные значения по белому цвету, поскольку в cmap ='coolwarm' белый цвет представляет nan/inf в этом интервале [vmin=-1, vmax=+1] после применения вышеупомянутых инструкций, однако у него есть 2 проблемы:

Во-первых, если в вашем наборе данных есть 0, он будет отображаться как пропущенные данные также белым цветом, и вы не сможете различить inf/nan и 0 в столбцах. Вторая проблема - вы даже не можете различить значения nan и inf!

Я также попытался mask=df.isnull() внутри sns.heatmap(), указав маску, в которой данные не будут отображаться для тех ячеек, значения маски которых равны True, но они снова охватывают 0 на основе этого ответа GH375, Я не уверен, что ответ здесь , упомянутый @ Scotty1, является правильным решением для моего случая, добавив marker, чтобы интерполировать значения на newdf = newdf.interpolate(). Это хорошая идея, чтобы отфильтровать недостающие данные путем поднабора:

import math
df = df[df['a'].apply(lambda x: math.isnan(x))]
df = df[df['a'] == float('inf')]

Мои сценарии выполняются, однако в цикле for я не смог получить правильный вывод из-за того, что в каждом цикле он печатает график каждого из них 3 раза с разными интервалами, например. он печатает A влево, затем снова печатает A под именем B и C в середине и справа в одном окне. Снова он печатает B 3 раза вместо одного раза и помещает его посередине, а в конце печатает C 3 раза вместо одного раза и кладет в правую сторону, он помещает в середину и влево!

import numpy as np
import pandas as pd
import os
import seaborn as sns
import matplotlib.pyplot as plt

#extract the parameters and put them in lists based on id_set
df = pd.read_csv('D:\SOF.TXT', header=None)
id_set = df[df.index % 4 == 0].astype('int').values
a = df[df.index % 4 == 1].values
b = df[df.index % 4 == 2].values
c = df[df.index % 4 == 3].values
data = {'A': a[:,0], 'B': b[:,0], 'C': c[:,0] }
#main_data contains all the data
main_data = pd.DataFrame(data, columns=['A','B','C'], index = id_set[:,0])  



#next iteration create all plots, change the numer of cycles
cycles = int(len(main_data)/480)
print(cycles)
for i in main_data:
    try:
        os.mkdir(i)
    except:
        pass
    min_val = main_data[i].min()
    min_nor = -1
    max_val = main_data[i].max()
    max_nor = 1
    for cycle in range(1):             #iterate thriugh all cycles range(1) by ====> range(int(len(main_data)/480))
        count =  '{:04}'.format(cycle)
        j = cycle * 480
        ordered_data = mkdf(main_data.iloc[j:j+480][i])
        csv = print_df(ordered_data)
        #Print .csv files contains matrix of each parameters by name of cycles respectively
        csv.to_csv(f'{i}/{i}{count}.csv', header=None, index=None)            
        if 'C' in i:
            min_nor = -40
            max_nor = 150
            #Applying normalizayion for C between [-40,+150]
            new_value = normalize(main_data.iloc[j:j+480][i].values, min_val, max_val, -40, 150)
            n_cbar_kws = {"ticks":[-40,150,-20,0,25,50,75,100,125]}
        else:
            #Applying normalizayion for A,B between    [-1,+1]
            new_value = normalize(main_data.iloc[j:j+480][i].values, min_val, max_val, -1, 1)
            n_cbar_kws = {"ticks":[-1.0,-0.75,-0.50,-0.25,0.00,0.25,0.50,0.75,1.0]}    
        Sections = mkdf(new_value)
        df = print_df(Sections)
        #Plotting parameters by using HeatMap
        plt.figure()
        sns.heatmap(df, vmin=min_nor, vmax=max_nor, cmap ='coolwarm', cbar_kws=n_cbar_kws)                             
        plt.title(i, fontsize=12, color='black', loc='left', style='italic')
        plt.axis('off')
        #Print .PNG iamges contains HeatMap plots of each parametersby name of cycles respectively
        plt.savefig(f'{i}/{i}{count}.png')  



    #plotting all columns ['A','B','C'] in-one-window side by side


    fig, axes = plt.subplots(nrows=1, ncols=3 , figsize=(20,10))
    plt.subplot(131)
    sns.heatmap(df, vmin=-1, vmax=1, cmap ="coolwarm", cbar=True , cbar_kws={"ticks":[-1.0,-0.75,-0.5,-0.25,0.00,0.25,0.5,0.75,1.0]})
    fig.axes[-1].set_ylabel('[MPa]', size=20) #cbar_kws={'label': 'Celsius'}
    plt.title('A', fontsize=12, color='black', loc='left', style='italic')
    plt.axis('off')

    plt.subplot(132)
    sns.heatmap(df, vmin=-1, vmax=1, cmap ="coolwarm", cbar=True , cbar_kws={"ticks":[-1.0,-0.75,-0.5,-0.25,0.00,0.25,0.5,0.75,1.0]})
    fig.axes[-1].set_ylabel('[Mpa]', size=20) #cbar_kws={'label': 'Celsius'}
    #sns.despine(left=True)
    plt.title('B', fontsize=12, color='black', loc='left', style='italic')
    plt.axis('off')

    plt.subplot(133)
    sns.heatmap(df, vmin=-40, vmax=150, cmap ="coolwarm" , cbar=True , cbar_kws={"ticks":[-40,150,-20,0,25,50,75,100,125]}) 
    fig.axes[-1].set_ylabel('[°C]', size=20) #cbar_kws={'label': 'Celsius'}
    #sns.despine(left=True)
    plt.title('C', fontsize=12, color='black', loc='left', style='italic')
    plt.axis('off')


    plt.suptitle(f'Analysis of data in cycle Nr.: {count}', color='yellow', backgroundcolor='black', fontsize=48, fontweight='bold')
    plt.subplots_adjust(top=0.7, bottom=0.3, left=0.05, right=0.95, hspace=0.2, wspace=0.2)
    #plt.subplot_tool()
    plt.savefig(f'{i}/{i}{i}{count}.png') 
    plt.show()

мой фрейм данных выглядит следующим образом:

          A          B            C
0      2.291171  -2.689658  -344.047912
10     2.176816  -4.381186  -335.936524
20     2.291171  -2.589725  -342.544885
30     2.176597  -6.360999     0.000000
40     2.577268  -1.993412  -344.326376
50     9.844076  -2.690917  -346.125859
60     2.061782  -2.889378  -346.375655

Ниже приведен обзор образца моего набора данных из файла .TXT: набор данных
в случае, если вы хотите проверить с отсутствующими значениями данных, измените последние 3 значения конца текстового файла на nan / inf, сохраните его и отладьте.

7590                  7590
0                     nan
7.19025828418         nan
-1738.000075          inf

Я бы хотел визуализировать большой пандас-фрейм данных, включающий 3 столбца columns=['A','B','C'] с помощью тепловых карт в одном окне. Этот фрейм данных имеет два типа переменных: строки (nan или inf) и числа с плавающей точкой. Я хочу, чтобы тепловая карта отображала отсутствующие ячейки данных внутри матричной квадратной модели фиксированными цветами, такими как nan черным и inf серебристым или серым, а остальная часть информационного кадра как обычная тепловая карта с плавающими в шкала cmap ='coolwarm'.

Вот изображение желаемого результата, если в наборе данных нет данных nan / inf:

desired image

Я с нетерпением жду ответа от тех людей, которые занимаются этими вопросами.

...