본문 바로가기
Daily Review

Matplotlib 차트를 향상시키는 7가지 간단한 방법

by data-analyst-luke 2022. 9. 12.
반응형
https://www.pexels.com/photo/person-holding-white-ipad-on-brown-wooden-table-6476589/

Matplotlib 는 Python 내에서 사용할 수 있는 가장 인기 있는 데이터 시각화 라이브러리 중 하나입니다 . 일반적으로 파이썬을 배울 때 접하는 첫 번째 데이터 시각화 라이브러리입니다. 몇 줄의 코드로 그림을 생성할 수 있지만 생성되는 플롯은 종종 형편없고 시각적으로 매력적이지 않으며 정보가 없습니다.

 

이를 방지하기 위해 몇 줄의 추가 코드로 그림의 통신 능력을 향상시킬 수 있습니다. 이 기사에서는 기본적인 matplotlib 산점도 에서 최종 사용자/독자에게 시각적으로 더 매력적이고 유익한 것으로 어떻게 갈 수 있는지 다룰 것 입니다.

 

matplotlib 수치를 향상하기 전과 후.   저자의 이미지.

 

라이브러리 및 데이터 가져오기

matplotlib 내에서 산점도를 향상할 수 있는 방법에 대한 다음 예에서는 Xeek 및 FORCE 2020 (Bormann et al., 2020)에서 실행하는 기계 학습 대회의 일부로 사용된 더 큰 데이터 세트의 하위 집합을 사용할 것입니다 . 이는 노르웨이 정부의 NOLD 2.0 라이선스에 따라 출시되었으며 자세한 내용은 NLOD(Open Government Data에 대한 노르웨이 라이선스) 2.0 에서 확인할 수 있습니다.

 

전체 데이터 세트는 https://doi.org/10.5281/zenodo.4351155 링크에서 액세스할 수 있습니다 .

이 튜토리얼에서는 matplotlib  pandas 를 모두 가져와야 합니다 .

 

그런 다음 pandas 메서드를 사용하여 데이터를 데이터 프레임으로 읽습니다 read_csv(). 또한 중성자 다공성에 대해 플롯하는 데 사용할 밀도 다공성 열을 계산합니다.

 

import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('data/Xeek_Well_15-9-15.csv')
df['DPHI'] = (2.65 - df['RHOB'])/1.65
df.describe()

 

위의 코드를 실행하면 새 DPHI 열이 포함된 다음 데이터 요약이 반환됩니다.

 

Xeek / Force 2020 데이터 세트의 15/9–15 웰 내의 웰 로그 측정에 대한 통계 요약입니다.   저자의 이미지.

기본 플롯 생성

 

데이터가 성공적으로 로드되면 첫 번째 산점도를 만들 수 있습니다. 이를 위해 x축에 중성자 다공성(NPHI)을 표시하고 y축에 밀도 다공성(DPHI)을 표시합니다.

 

또한 그림 크기를 10 x 8로 설정합니다.

plt.figure(figsize=(10,8))
plt.scatter(df['NPHI'], df['DPHI'])

 

 

이 두 줄의 코드를 사용하여 위의 플롯을 얻습니다. 아주 밋밋해 보이지 않나요? 시각적으로 더 매력적으로 만들고 데이터에 대한 통찰력을 얻을 수 있도록 색상을 추가해 보겠습니다.

 

세 번째 변수로 색상 추가하기

 

이를 위해 감마선(GR)으로 데이터에 색상을 지정하고 색상 범위를 0에서 100( vmin및 vmax매개변수) 사이로 설정합니다.

plt.colorbar()를 사용하여 색상 막대를 표시해야 합니다.

 

plt.xlim()마지막으로 및 를 호출하여 차트의 x 및 y 제한을 0에서 0.8로 설정합니다 plt.ylim(). 이렇게 하면 두 축이 모두 0에서 시작하여 최대 0.8이 됩니다.

 

plt.figure(figsize=(10,8))
plt.scatter(df['NPHI'], df['DPHI'], c=df['GR'], vmin=0, vmax=100, cmap='viridis_r')
plt.xlim(0, 0.8)
plt.ylim(0, 0.8)
plt.colorbar()

우리가 사용하는 컬러 맵은 반대로 Viridis입니다. 이 색상 맵은 균일성을 유지하고 색맹 친화적이면서 높은 값과 낮은 값 사이에 좋은 대비를 제공합니다.

위의 코드를 실행하면 다음 플롯이 반환됩니다.

 

밀도 다공성 대 중성자 다공성을 보여주는 matplotlib의 기본 산점도.   저자의 이미지.

 

컬러 맵 선택에 대해 자세히 알아보고 일부 컬러 맵이 모든 사람에게 적합하지 않은 이유를 알고 싶다면 여기에서 이 비디오를 확인하는 것이 좋습니다.

 

 

플롯에서 척추 제거

 

다음으로 변경할 사항은 플롯을 둘러싸고 있는 블랙박스를 제거하는 것입니다. 이 상자의 각 면을 척추라고 합니다. 상단과 오른쪽을 제거하면 플롯이 더 깔끔하고 시각적으로 매력적입니다.

 

plt.gca().spines[side].set_visible(False)측면이 위쪽, 오른쪽, 왼쪽 또는 아래쪽이 될 수 있는 위치 를 호출하여 오른쪽 및 위쪽 축을 제거할 수 있습니다.

 

plt.figure(figsize=(10,8))
plt.scatter(df['NPHI'], df['DPHI'], c=df['GR'], vmin=0, vmax=100, cmap='viridis_r')
plt.xlim(0, 0.8)
plt.ylim(0, 0.8)
plt.colorbar()
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)

 

가시를 제거하면 플롯이 더 깨끗해 보이고 덜 복잡해 보입니다. 또한 색상 막대는 이제 분할된 것처럼 보이기보다는 플롯의 일부처럼 느껴집니다.

 

오른쪽 및 위쪽 가시(가장자리)를 제거한 후 Matplotlib 산점도.   저자의 이미지.

제목 및 축 레이블 추가

 

위의 산점도를 보면 각 축이 무엇을 나타내는지 알 수 있지만 다른 사람들은 이 플롯이 무엇에 관한 것인지, 색상이 나타내는 것과 무엇에 대해 플롯된 것인지를 어떻게 이해할까요?

 

플롯에 제목과 축 레이블을 추가하는 것은 효과적인 시각화를 만드는 데 필수적인 부분입니다. 다음을 사용하여 간단히 추가할 plt.xlabel수 plt.ylabel있습니다 plt.title. 이들 각각 내에서 우리가 표시하고자 하는 텍스트와 글꼴 크기와 같은 글꼴 속성을 전달합니다.

 

또한 레이블에 측정 단위를 포함하는 것이 좋습니다. 이것은 독자가 줄거리를 더 잘 이해하는 데 도움이 됩니다.

 

plt.figure(figsize=(10,8))
plt.scatter(df['NPHI'], df['DPHI'], c=df['GR'], vmin=0, vmax=100, cmap='viridis_r')
plt.xlim(0, 0.8)
plt.ylim(0, 0.8)
plt.colorbar(label='Gamma Ray (API)')
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)
plt.title('Density Porosity vs Neutron Porosity Scatter Plot', fontsize=14, fontweight='bold')
plt.xlabel('Neutron Porosity (dec)')
plt.ylabel('Density Porosity (dec)')
plt.show()

 

위의 코드를 실행하면 다음 플롯을 얻습니다. 축에 무엇이 그려져 있는지, 차트가 무엇에 관한 것인지, 색상 범위가 무엇을 나타내는지 바로 알 수 있습니다.

 

축에 제목과 레이블을 추가한 후 Matplotlib 산점도.   저자의 이미지.

희미한 격자 추가(선택 사항)

 

플롯의 목적에 따라 차트 독자가 플롯을 시각적으로 쉽게 탐색할 수 있도록 그리드를 추가할 수 있습니다. 이것은 플롯에서 값을 정량적으로 추출하려는 경우 특히 중요합니다. 그러나 그리드 선이 "쓰레기"로 간주되어 그대로 두는 것이 가장 좋은 경우가 있습니다. 예를 들어 데이터 세트 내에서 일반적인 추세만 표시하고 독자가 원시 값에 너무 많이 집중하는 것을 원하지 않는 경우입니다.

 

이 예에서는 데이터를 너무 많이 손상시키지 않도록 희미한 눈금선을 추가합니다. 이렇게 하려면 plt.grid()코드에 추가해야 합니다.

 

plt.figure(figsize=(10,8))
plt.scatter(df['NPHI'], df['DPHI'], c=df['GR'], vmin=0, vmax=100, cmap='viridis_r')
plt.xlim(0, 0.8)
plt.ylim(0, 0.8)
plt.colorbar(label='Gamma Ray (API)')
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)
plt.title('Density Porosity vs Neutron Porosity Scatter Plot', fontsize=14, fontweight='bold')
plt.xlabel('Neutron Porosity (dec)')
plt.ylabel('Density Porosity (dec)')
plt.grid()
plt.show()

 

그러나 이렇게 하면 그리드 선이 플롯 상단에 나타나고 시각적으로 매력적으로 보이지 않습니다.

 

격자선을 추가한 후 Matplotlib 산점도.   저자의 이미지.

 

그리드 선을 뒤에 표시하려면 에 대한 매개변수를 호출하고 추가 plt.grid()하기 전에 선 을 이동해야 합니다 . 차트의 구성 요소가 그려지는 순서를 제어합니다. 이 값은 플롯의 다른 항목에 상대적이라는 점에 유의해야 합니다.plt.scatter()zorder

 

그리드의 zorder경우 산점도에 사용하는 값보다 작은 값을 원합니다. 이 예에서는 zorder그리드에 대해 1로 설정하고 산점도에 대해 2로 설정했습니다.

 

또한 그리드에 대한 몇 가지 매개변수, 즉 color그리드 선의 색상을 alpha제어하고 선의 투명도를 제어하는 ​​매개변수를 추가합니다.

 

plt.figure(figsize=(10,8))
plt.grid(color='lightgray', alpha=0.5, zorder=1)
plt.scatter(df['NPHI'], df['DPHI'], c=df['GR'], vmin=0, vmax=100, cmap='viridis_r', zorder=2)
plt.xlim(0, 0.8)
plt.ylim(0, 0.8)
plt.colorbar(label='Gamma Ray (API)')
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)
plt.title('Density Porosity vs Neutron Porosity Scatter Plot', fontsize=14, fontweight='bold')
plt.xlabel('Neutron Porosity (dec)')
plt.ylabel('Density Porosity (dec)')
plt.show()

 

이것은 훨씬 더 멋진 플롯을 반환하고 그리드 선이 너무 산만하지 않습니다.

 

격자선이 플롯의 뒤쪽과 데이터 뒤쪽으로 이동된 후 Matplotlib 산점도.   저자의 이미지.

포인트 크기 변경

 

다음은 각 데이터 포인트의 크기를 변경하는 것입니다. 현재 포인트는 상대적으로 크고 데이터 밀도가 높은 곳에서는 데이터 포인트가 서로 겹칠 수 있습니다.

 

이에 대응하는 한 가지 방법은 데이터 포인트의 크기를 줄이는 것입니다. 이것은 함수 s내의 매개변수 를 통해 달성됩니다 plt.scatter(). 이 예에서는 5로 설정합니다.

 

plt.figure(figsize=(10,8))
plt.grid(color='lightgray', alpha=0.5, zorder=1)
plt.scatter(df['NPHI'], df['DPHI'], c=df['GR'], vmin=0, vmax=100, zorder=2, s=5, cmap='viridis_r')
plt.xlim(0, 0.8)
plt.ylim(0, 0.8)
plt.colorbar(label='Gamma Ray (API)')
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)
plt.title('Density Porosity vs Neutron Porosity Scatter Plot', fontsize=14, fontweight='bold')
plt.xlabel('Neutron Porosity (dec)')
plt.ylabel('Density Porosity (dec)')
plt.show()

 

이 코드를 실행하면 데이터 내에서 더 많은 변화를 볼 수 있고 포인트의 실제 위치에 대해 더 잘 알 수 있습니다.

 

포인트 크기를 변경한 후 matplotlib 산점도.   저자의 이미지.

 


주석 달기

 

데이터 시각화를 생성할 때 독자의 관심을 특정 관심 지점으로 이끌고 싶을 때가 종종 있습니다. 여기에는 비정상적인 데이터 포인트 또는 주요 결과가 포함될 수 있습니다.

 

주석을 추가하려면 다음 줄을 사용할 수 있습니다.

 

plt.annotate('Text We Want to Display', xy=(x,y), xytext=(x_of_text, y_of_text)

 

xy는 차트에서 가리키고자 하는 지점이고  xytext텍스트의 위치입니다.

 

원하는 경우 텍스트에서 차트의 한 지점까지 화살표 지점을 포함할 수도 있습니다. 이것은 텍스트 주석이 문제의 지점에서 더 멀리 떨어져 있는 경우에 유용합니다.

 

또한 점을 더 강조 표시하거나 점이 존재하지 않는 곳에 추가하려면 기존 산점도 위에 다른 산점도를 추가하고 단일 x 및 y 값과 해당 색상 및 스타일을 전달할 수 있습니다.

 

plt.figure(figsize=(10,8))
plt.grid(color='lightgray', alpha=0.5, zorder=1)
plt.scatter(df['NPHI'], df['DPHI'], c=df['GR'], vmin=0, vmax=100, cmap='viridis_r',
            zorder=2, s=5)
plt.xlim(0, 0.8)
plt.ylim(0, 0.8)
plt.colorbar(label='Gamma Ray (API)')
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)
plt.title('Density Porosity vs Neutron Porosity Scatter Plot', fontsize=14, fontweight='bold')
plt.xlabel('Neutron Porosity (dec)')
plt.ylabel('Density Porosity (dec)')
plt.scatter(0.42 ,0.17, color='red', marker='o', s=100, zorder=3)
plt.annotate('Shale Point', xy=(0.42 ,0.17), xytext=(0.5, 0.05),
             fontsize=12, fontweight='bold', 
             arrowprops=dict(arrowstyle='->',lw=3), zorder=4)
plt.show()

 

이 코드가 실행되면 다음 플롯이 다시 나타납니다. 플롯에서 빨간색 원으로 강조 표시된 잠재적 셰일 포인트와 화살표가 가리키는 깨끗한 주석이 있음을 알 수 있습니다.

 

matplotlib 밀도 다공성 대 중성자 다공성의 산점도(텍스트 주석 및 화살표 포함).   저자의 이미지.

 


선택된 점은 단지 강조를 위한 것이며 이 데이터 내에서 진정한 셰일 점을 식별하려면 더 자세한 해석이 필요합니다.

 

관심 영역 강조 표시

 

강조 표시하려는 플롯의 전체 영역이 있는 경우 해당 영역을 음영 처리하기 위해 간단한 직사각형(또는 다른 모양)을 추가할 수 있습니다.

 

이를 위해 다음 라인에서 import한 후 호출해야 Rectangle합니다 matplotlib.patches.

 

plt.gca().add_patch(Rectangle((x_position, y_position), width, height, alpha=0.2, color='yellow'))

 

및는 사각형의 왼쪽 하단 모서리를 나타냅니다 x_position. y_position거기에서 너비와 높이가 추가됩니다.

 

해당 영역이 나타내는 내용을 나타내는 텍스트를 추가할 수도 있습니다.

 

plt.text(x_position, y_position, s='Text You Want to Display, fontsize=12, fontweight='bold', ha='center', color='grey')

 

ha텍스트를 가로로 배치하는 데 사용됩니다. center로 설정하면 x_position 및 y_position은 텍스트 문자열의 중심을 나타냅니다. 왼쪽으로 설정된 경우 x_position 및 y_position은 해당 텍스트 문자열의 왼쪽 가장자리를 나타냅니다.

 

from matplotlib.patches import Rectangle
plt.figure(figsize=(10,8))
plt.grid(color='lightgray', alpha=0.5, zorder=1)
plt.scatter(df['NPHI'], df['DPHI'], c=df['GR'], vmin=0, vmax=100, cmap='viridis_r',
            zorder=2, s=5)
plt.xlim(0, 0.8)
plt.ylim(0, 0.8)
plt.colorbar(label='Gamma Ray (API)')
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)
plt.title('Density Porosity vs Neutron Porosity Scatter Plot', fontsize=14, fontweight='bold')
plt.xlabel('Neutron Porosity (dec)')
plt.ylabel('Density Porosity (dec)')
plt.scatter(0.42 ,0.17, color='red', marker='o', s=100, zorder=3)
plt.annotate('Shale Point', xy=(0.42 ,0.17), xytext=(0.5, 0.05),
             fontsize=12, fontweight='bold', 
             arrowprops=dict(arrowstyle='->',lw=3), zorder=4)
plt.text(0.6, 0.75, s='Possible Washout Effects', fontsize=12, fontweight='bold', ha='center', color='grey')
plt.gca().add_patch(Rectangle((0.4, 0.4), 0.4, 0.4, alpha=0.2, color='yellow'))
plt.show()

 

이 코드는 영역이 강조 표시된 다음 플롯을 반환합니다.

 

음영 처리된 영역을 추가한 후 matplotlib 산점도를 사용하여 세척으로 인한 잠재적 영향을 강조 표시합니다.   저자의 이미지.

요약

 

이 짧은 튜토리얼에서 우리는 matplotlib 에 의해 생성된 기본 산점도에서 훨씬 더 읽기 쉽고 시각적으로 매력적인 산점도로 이동하는 방법을 보았습니다. 이것은 약간의 작업으로 우리가 다른 사람들과 공유할 수 있고 쉽게 우리의 이야기를 전달할 수 있는 훨씬 더 나은 줄거리를 얻을 수 있음을 보여줍니다.

 

우리는 스파인을 제거하고, 정성적 분석에 도움이 되도록 눈금선을 추가하고, 표시하는 내용을 표시하기 위해 제목과 레이블을 추가하고, 독자의 주의를 끌고자 하는 핵심 요점을 강조하여 불필요한 혼란을 제거하는 방법을 보았습니다.

 

matplotlib 수치를 향상하기 전과 후.   저자의 이미지.
 
반응형

댓글