728x90
반응형
이번 포스팅에서는 지난 포스팅에 이어서
x축과 y축 2개(2개 변수) 를 기준으로 산점도를 그리고,
산점도 위에 변수 별로 추세선을 그리는 스크립트를 공유하고자 합니다.
사실 지난 글에서 그룹별 색상을 표현하는 코드를 먼저 만든 후에
그룹별로 모두 색깔을 나눠서 볼 경우 그래프 가독성이 떨어지는 문제가 생기더라구요.
그래서 이제 그룹별 색깔 구분을 없애고, y축 2개에 표현되는 변수만 2개의 색깔로 구분하도록
스크립트를 수정해서 다시 공유해요~!
https://woomii.tistory.com/18
함수 설명
def ScatterPlotting_2yaxis
- x, y1, y2 : 그래프에 나타내고자 하는 수치 데이터
- group : 그래프에 나타내고자 하는 그룹(카데고리)
- save_path='C:/' : 그래프 그림 파일 저장 경로
- input_figsize=(7, 6) : 그림 크기 설정
- ssize_setting = 30 : 산점도의 점 크기 설정
- alpha_setting = 0.5 : 산점도의 점 투명도 설정
- fontsize_setting = 8 : 그래프 축, 제목 등 텍스트 폰트 크기 설정
- axis_labels=('x', 'y1', 'y2') : x축, y축(좌측), y축(우측) 라벨 설정
- group_coloring = True : 그룹별 색상 구분 True 일 경우 반영, False일 경우 그룹별 색상 동일
전체 코드
def ScatterPlotting_2yaxis(x, y1, y2, group, save_path='C:/',
input_figsize=(7, 6), ssize_setting = 30, alpha_setting = 0.5, fontsize_setting = 8,
axis_labels=('x', 'y1', 'y2'), group_coloring = True):
os.chdir(save_path)
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.set_ylim(0, max(y1)*1.1)
ax2.set_ylim(0, max(y2)*1.1)
ax1.grid(True)
ax1.set_xlabel(axis_labels[0], fontsize=fontsize_setting)
if group_coloring == True:
df = pd.concat([x, y1, y2, group], axis=1)
df.columns = ['x', 'y1', 'y2', 'group']
c_lst = [plt.cm.Paired(a) for a in np.linspace(0.0, 1.0, 2 * len(set(df['group'])))]
group_lst = df.groupby('group', as_index=False).mean().group.tolist()
print(df, group_lst)
# y1
for i, g in enumerate(df.groupby('group')):
# calc the trendline
z = np.polyfit(g[1]['x'].tolist(), g[1]['y1'].tolist(), 1)
p = np.poly1d(z)
ax1.scatter(x=g[1]['x'], y=g[1]['y1'], color=c_lst[i], label='{}_{}'.format(group_lst[i], axis_labels[1]),
s=ssize_setting, alpha=alpha_setting)
ax1.set_ylabel(axis_labels[1], fontsize = fontsize_setting)
ax1.plot(g[1]['x'], p(g[1]['x']), color = c_lst[i], linestyle = "-.", label='{}_{}_line'.format(group_lst[i], axis_labels[1]))
# y2
for i, g in enumerate(df.groupby('group')):
# calc the trendline
z2 = np.polyfit(g[1]['x'].tolist(), g[1]['y2'].tolist(), 1)
p2 = np.poly1d(z2)
ax2.scatter(x=g[1]['x'], y=g[1]['y2'], color = c_lst[len(set(df['group'])) + i], label='{}_{}'.format(group_lst[i], axis_labels[2]),
s=ssize_setting, alpha=alpha_setting)
ax2.set_ylabel(axis_labels[2], fontsize = fontsize_setting)
ax2.plot(g[1]['x'], p2(g[1]['x']), color = c_lst[len(set(df['group'])) + i]
, linestyle = ":", label='{}_{}_line'.format(group_lst[i], axis_labels[2]))
# ask matplotlib for the plotted objects and their labels
sct1, labels1 = ax1.get_legend_handles_labels()
sct2, labels2 = ax2.get_legend_handles_labels()
ax2.legend(sct1 + sct2, labels1 + labels2, fontsize = 'small', loc='center left', bbox_to_anchor=(1.1, 0.5))
plt.title(axis_labels[0] + '_' + axis_labels[1] + '/' + axis_labels[2] +
"[" + str(len(group_lst)) + "groups_" + str(len(x)) + "])", fontsize=fontsize_setting*1.2)
saveNm_fig = '{}_{}_{}_{}groups_scatterplot_{}.png'.format(axis_labels[0], axis_labels[1], axis_labels[2], str(len(group_lst)), str(len(x)))
else: # 전체 데이터를 동일 색깔로 표시
# calc the trendline
z = np.polyfit(x, y1, 1)
p = np.poly1d(z)
ax1.scatter(x = x, y = y1, s=ssize_setting, alpha=alpha_setting, color = 'red', label = axis_labels[1])
ax1.set_ylabel(axis_labels[1], fontsize = fontsize_setting)
ax1.plot(x, p(x), "r:", label='{}_line'.format(axis_labels[1]))
z = np.polyfit(x, y2, 1)
p = np.poly1d(z)
ax2.scatter(x = x, y = y2, s=ssize_setting, alpha=alpha_setting, color = 'green', label = axis_labels[2])
ax2.set_ylabel(axis_labels[2], fontsize = fontsize_setting)
ax2.plot(x, p(x), "g:", label='{}_line'.format(axis_labels[2]))
# ask matplotlib for the plotted objects and their labels
sct1, labels1 = ax1.get_legend_handles_labels()
sct2, labels2 = ax2.get_legend_handles_labels()
ax2.legend(sct1 + sct2, labels1 + labels2, fontsize = 'small', loc='center left', bbox_to_anchor=(1.1, 0.5))
plt.title(axis_labels[0] + '_' + axis_labels[1] + '/' + axis_labels[2] +
"[" + str(len(x)) + "])", fontsize=fontsize_setting*1.2)
saveNm_fig = '{}_{}_{}_scatterplot_{}.png'.format(axis_labels[0], axis_labels[1], axis_labels[2], str(len(x)))
plt.savefig(fname=saveNm_fig, dpi=300, bbox_inches='tight')
plt.show()
출력 결과
ScatterPlotting_2yaxis(
x = df.sepal_length, y1 = df.sepal_width, y2 = df.petal_length, group = df.group,
save_path='D:/', input_figsize=(7, 6), ssize_setting = 20, alpha_setting = 0.5, fontsize_setting = 11,
axis_labels=('sepal_length', 'sepal_width', 'petal_length'),
group_coloring = True)
ScatterPlotting_2yaxis(
x = df.sepal_length, y1 = df.sepal_width, y2 = df.petal_length, group = df.group,
save_path='D:/', input_figsize=(7, 6), ssize_setting = 20, alpha_setting = 0.5, fontsize_setting = 11,
axis_labels=('sepal_length', 'sepal_width', 'petal_length'),
group_coloring = False)
반응형
'Data Analysis > visualization' 카테고리의 다른 글
[번역] 모든 데이터 과학자가 시각화 툴킷에 추가해야 하는 8가지 대안 (1) | 2023.11.22 |
---|---|
[python] 데이터프레임에서 수치형 컬럼 자동 선택 후 그룹별 박스플롯 그리기! (feat. seaborn) (0) | 2022.04.27 |
[python] 데이터프레임에서 수치형 컬럼 자동 선택 후 히스토그램 한 판에 그리기! (feat. seaborn) (0) | 2022.04.26 |
[Python] y축 2개를 이용한 산점도 + 추세선 그리기(&그룹별 색상) (0) | 2022.02.10 |
[Python] 산점도 : 2개의 변수 간 분포 확인을 위한 시각화 방법(한눈에 들어오는 예제 코드 포함) (0) | 2022.01.27 |