[python] heatmap 색상바꾸기(컬러맵 만들기)

반응형
    반응형

    heatmap 글을 쓰다보니 양이 많아 포스팅을 새로 합니다.

    데이터는 heatmap 그리기 포스팅에서 했던 예제를 그대로 쓰겠습니다.

    import pandas as pd
    import matplotlib.pyplot as plt
    import numpy as np
    
    data = np.random.randn(10,10)
    columns = ['X' + str(x).zfill(1) for x in range(10)]
    df = pd.DataFrame(data,columns=columns)
    df.index = ['Y' + str(x).zfill(1) for x in range(10)]

     

    matplotlib에서 제공되는 컬러맵

    matplotlib에는 다양한 색상군이 있는데 아래 링크에서 볼 수 있습니다.

    https://matplotlib.org/stable/tutorials/colors/colormaps.html

     

    Choosing Colormaps in Matplotlib — Matplotlib 3.5.1 documentation

    Colormaps are often split into several categories based on their function (see, e.g., [Moreland]): First, we'll show the range of each colormap. Note that some seem to change more "quickly" than others. Sequential2 Many of the \(L^*\) values from the Seque

    matplotlib.org

    matplotlib에서 제공하는 cmap을 가지고 heatmap의 색상을 바꿀 수 있습니다.

    binary를 사용해보겠습니다.

    plt.imshow(df,cmap='binary',interpolation='none')
    plt.colorbar()
    plt.xticks(range(len(df.columns)),df.columns)
    plt.yticks(range(len(df)), df.index)
    plt.show()

     

    나만의 컬러맵 만들기

    나만의 컬러맵 만들수도 있지만 약간 복잡합니다.
    matplotlib.colors.LinearSegmentedColormap.from_list로 컬러맵을 만들 수 있습니다.

    파라미터는 다음과 같습니다.

    • name : 컬러맵의 이름 정하기
    • colors : 컬러 넣기(rgb형식일때는 array 형식으로 넣어야 한다), 색상코드는 리스트형식으로 가능
    • N : rgb 양자화 수준. 디폴트 256
    • gamma : float, 색상의 정도 값이 클수록 확연하게 구분됨

    색상코드로 컬러맵 만들기

    색상코드를 이용해 컬러맵을 구성하려면 전문가가 아닌 이상 정확하게 색 구성을 어떻게 할 것인지부터 막연합니다. 거기다 색상코드를 알길이 없는데 하나씩 색상을 집어내면 기존의 색상과의 비교를 할 수가 없어서 아주 난감해집니다. 색상비교를 할 수 있는 곳을 찾아보다가 알게된 사이트가 있습니다. 바로 adobe colors 입니다.
    adobe colors palette(color-wheel)를 이용하면 조금이나마 막연함을 줄일 수 있습니다.
    adobe color 에 들어가면 color-wheel 이라는 곳에서 다양한 색체 휠로 돌려보면서 원하는 색상군을 찾을 수 있고 로그인할시 색상군을 저장할 수도 있는 것 같습니다. 저장기능이 있어서 adobe colors palette라고 부르는 것 같습니다.

    다음 링크에서 색상 비교를 해보시기 바랍니다.


    https://color.adobe.com/ko/create/color-wheel

     

    https://color.adobe.com/ko/create/color-wheel

     

    color.adobe.com

    다시 돌아와 컬러맵을 만들어보겠습니다.
    위 그림처러 사용자 정의를 선택해 임의로 5개의 color-wheel로 색상을 정하고 색상코드를 가져왔습니다. 보라색 계통으로 색을 만들겠습니다.

    from matplotlib.colors import LinearSegmentedColormap
    colors = ['#FFFFFF','#CF7CDE','#B472CC','#A468BA','#7E508F']
    cmap = LinearSegmentedColormap.from_list('my_cmap',colors,gamma=2)
    cmap

    cmap을 보면 my_cmap이라는 이름과 함께 컬러맵이 생성되었습니다.
    이제 생성한 컬러맵을 heatmap에 적용시킵니다.

    plt.imshow(df,cmap=cmap,interpolation='none')
    plt.colorbar()
    plt.xticks(range(len(df.columns)),df.columns)
    plt.yticks(range(len(df)), df.index)
    plt.show()

    rgb로 컬러맵 만들기

    rgb로 하면 굉장히 간편하게 할 수 있을것 같지만 from_list에서는 0~1 사이의 값만 허용하므로 굉장히 난감합니다. 또한, heatmap의 사용하려면 색상의 채도만 변하는 게 좋을 수 있는데 rgb로 채도만 바뀐 색상 rgb코드를 알아내는게 굉장히 어렵습니다.
    이런 경우는 HSV 색 공간을 사용하면 좋습니다.
    HSV 색 공간은 색상(Hue),채도(Saturation), 명도(Value)의 좌표로 색상을 표현한 지표입니다.

    이를 이용해 색상을 하나 고르고 채도만 변경하면 그럴듯한 컬러맵이 나옵니다.
    HSV를 확인하려면 구글에서 color picker라 칩니다.
    맨 위에 색상 선택도구가 나옵니다. 여기서 HSV를 확인할 수 있습니다.

    색상을 정하고 채도만 바꾸어서 HSV를 RGB로 바꿔줍니다.
    채도만 변경한 컬러맵(white, 빨강(채도50%), 빨강(채도100%))으로 만들어보겠습니다.
    명도(Value)는 그림처럼 하지 않고 최대로 해서 1로 고정하겠습니다.

    import matplotlib.colors as mcl
    h = 4
    s = 0.99 #현재 예제에선 필요없음
    v = 1
    #colors = [white,빨강(채도50%),빨강(채도100%)]
    # rgb로 변경 -> mcl.hsv_to_rgb(h,s,v)
    
    colors = [
        mcl.hsv_to_rgb((h/360,0,v)),
        mcl.hsv_to_rgb((h/360,0.5,v)),
        mcl.hsv_to_rgb((h/360,1,v))
    ]
    
    cmap = LinearSegmentedColormap.from_list('my_cmap',colors,gamma=2)
    
    cmap

    이를 다시 heatmap에 넣으면 빨강의 heatmap을 만들게 됩니다.

    plt.imshow(df,cmap=cmap,interpolation='none')
    plt.colorbar()
    plt.xticks(range(len(df.columns)),df.columns)
    plt.yticks(range(len(df)), df.index)
    plt.show()

     

    관련 포스팅

    [Python/그래프 그리기] - [Pyhon]heatmap 그리기,텍스트 넣기

     

    댓글

    Designed by JB FACTORY

    ....