TOP
class="layout-aside-left paging-number">
본문 바로가기
[파이썬 Projects]/<파이썬 데이터 분석>

[파이썬] 프로젝트 : 웹 페이지 구축 - 4 (데이터 시각화)

by 기록자_Recordian 2025. 3. 20.
728x90
반응형
이전 내용
 

[파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 3

이전 내용 [파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 2이전 내용  [파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 1프로젝트 개요 2차 프로젝트를 시작하게 되었다.이번에 해야할

puppy-foot-it.tistory.com


시각화 작업
연령대별 분석

 

1. 각 지역의 연령별 방문자수 및 참여자수

기존에 만들어둔 누적 막대그래프 생성 코드를 응용하여 누적막대그래프 생성

- 연령별 방문자수 누적 막대그래프

# 데이터 집계 및 병합
off_df_age = off_df.groupby(['연령대', '날짜', '지역']).agg({'방문자수': 'sum', '참여자수': 'sum'}).reset_index()

# 컬럼 이름 변경
off_df_age.rename(columns={'지역': 'CITY', '방문자수': 'VISITORS', '참여자수': 'PART', '날짜': 'DATE', '연령대': 'AGE'}, inplace=True)

# 날짜를 datetime으로 형변환
off_df_age['DATE'] = pd.to_datetime(off_df_age['DATE'])

# 참여율 칼럼 추가
off_df_age['P_Ratio'] = (off_df_age['PART'] / off_df_age['VISITORS']) * 100

# 'DATE'를 월 단위로 그룹화하고 각 지역별 방문자 수를 합산
monthly_visit_age = off_df_age.groupby(['CITY', 'AGE', pd.Grouper(key='DATE', freq='M')])['VISITORS'].sum().reset_index()

# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_visit_age.pivot_table(index='CITY', columns='AGE', values='VISITORS', fill_value=0)

# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))

# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)

# 각 연령대별로 누적 값 추가
for age in pivoted_data.columns:
    plt.bar(pivoted_data.index, pivoted_data[age], bottom=bottom_values, label=age)
    bottom_values += pivoted_data[age]

# 그래프 꾸미기
plt.title('연령대별 방문자수')  # 제목 추가
plt.xlabel('지역')  # x축 라벨 추가
plt.ylabel('누적 방문자수')  # y축 라벨 추가
plt.legend(title='연령대', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10)  # 범례 설정
plt.xticks(rotation=45)  # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1])  # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show()  # 그래프 출력

- 연령별 참여자수 누적 막대그래프

# 'DATE'를 월 단위로 그룹화하고 각 지역별 참여자 수를 합산
monthly_part_age = off_df_age.groupby(['CITY', 'AGE', pd.Grouper(key='DATE', freq='M')])['PART'].sum().reset_index()

# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_part_age.pivot_table(index='CITY', columns='AGE', values='PART', fill_value=0)

# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))

# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)

# 각 연령대별로 누적 값 추가
for age in pivoted_data.columns:
    plt.bar(pivoted_data.index, pivoted_data[age], bottom=bottom_values, label=age)
    bottom_values += pivoted_data[age]

# 그래프 꾸미기
plt.title('연령대별 참여자수')  # 제목 추가
plt.xlabel('지역')  # x축 라벨 추가
plt.ylabel('누적 참여자수')  # y축 라벨 추가
plt.legend(title='연령대', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10)  # 범례 설정
plt.xticks(rotation=45)  # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1])  # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show()  # 그래프 출력

 

2. 연령대별 방문 및 참여 비율

- 연령대별 방문 비율 (파이차트)

# 데이터 집계
vis_age = off_df_age.groupby(['AGE'])['VISITORS'].sum().reset_index()

labels = vis_age['AGE'].unique()
explode = [0.1 for _ in range(len(labels))]  # 모든 섹터를 약간 부풀리기

# 색상 팔레트 설정
colors = sns.color_palette("Set2", len(labels))

plt.pie(data = vis_age, x='VISITORS', labels=labels, autopct='%.1f%%',startangle=260, 
         colors=colors, explode=explode, shadow=True)
plt.title("연령대별 방문율")
plt.show()

▶ 가상 데이터라 그런지 연령대별로 데이터가 균등하게 나눠져 있음을 알 수 있다.

 

- 월간 연령대별 방문자수 그래프

# 시각화
plt.figure(figsize=(12, 9))
sns.lineplot(data=monthly_visit_age, x='DATE', y='VISITORS', hue='AGE', palette='Set1')

# 그래프 꾸미기
plt.legend(loc='upper center', ncol=4, bbox_to_anchor=(0.5, 1))
plt.title('월간 연령대별 방문자수')
plt.xlabel('날짜')
plt.ylabel('수')
plt.xticks(rotation=45)
plt.grid(True)
plt.tight_layout()
plt.show()

 

- 월간 연령대별 참여자수 그래프

# 시각화
plt.figure(figsize=(12, 9))
sns.lineplot(data=monthly_part_age, x='DATE', y='PART', hue='AGE', palette='Set2')

# 그래프 꾸미기
plt.legend(loc='upper center', ncol=4, bbox_to_anchor=(0.5, 1))
plt.title('월간 연령대별 참여자수')
plt.xlabel('날짜')
plt.ylabel('수')
plt.xticks(rotation=45)
plt.grid(True)
plt.tight_layout()
plt.show()

 

- 연령대별 참여 비율 (파이차트)

# 데이터 집계
part_age = off_df_age.groupby(['AGE'])['PART'].sum().reset_index()

labels = part_age['AGE'].unique()
explode = [0.1 for _ in range(len(labels))]  # 모든 섹터를 약간 부풀리기

# 색상 팔레트 설정
colors = sns.color_palette("Set3", len(labels))

plt.pie(data = part_age, x='PART', labels=labels, autopct='%.1f%%',startangle=260, 
         colors=colors, explode=explode, shadow=True)
plt.title("연령대별 참여율")
plt.show()

 

▶ 가상 데이터라 그런지 연령대별로 데이터가 균등하게 나눠져 있음을 알 수 있다.

 

- 각 캠페인의 연령대별 방문자수 누적 막대그래프 그리기

# 데이터 집계 및 병합
off_df_ev_age = off_df.groupby(['연령대', '날짜', '이벤트 종류']).agg({'방문자수': 'sum', '참여자수': 'sum'}).reset_index()

# 컬럼 이름 변경
off_df_ev_age.rename(columns={'이벤트 종류': 'CAMP', '방문자수': 'VISITORS', '참여자수': 'PART', '날짜': 'DATE', '연령대': 'AGE'}, inplace=True)

# 날짜를 datetime으로 형변환
off_df_ev_age['DATE'] = pd.to_datetime(off_df_ev_age['DATE'])

# 참여율 칼럼 추가
off_df_ev_age['P_Ratio'] = (off_df_ev_age['PART'] / off_df_ev_age['VISITORS']) * 100

# 'DATE'를 월 단위로 그룹화하고 각 캠페인별 참여자 수를 합산
monthly_visit_ev_age = off_df_ev_age.groupby(['CAMP', 'AGE', pd.Grouper(key='DATE', freq='M')])['VISITORS'].sum().reset_index()

# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_visit_ev_age.pivot_table(index='CAMP', columns='AGE', values='VISITORS', fill_value=0)

# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))

# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)

# 각 연령대별로 누적 값 추가
for age in pivoted_data.columns:
    plt.bar(pivoted_data.index, pivoted_data[age], bottom=bottom_values, label=age)
    bottom_values += pivoted_data[age]

# 그래프 꾸미기
plt.title('캠페인-연령대별 방문자수')  # 제목 추가
plt.xlabel('캠페인')  # x축 라벨 추가
plt.ylabel('누적 방문자수')  # y축 라벨 추가
plt.legend(title='연령대', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10)  # 범례 설정
plt.xticks(rotation=45)  # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1])  # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show()  # 그래프 출력

 

- 각 캠페인의 연령대별 참여자수 누적 막대그래프 그리기

# 'DATE'를 월 단위로 그룹화하고 각 캠페인별 참여자 수를 합산
monthly_part_ev_age = off_df_ev_age.groupby(['CAMP', 'AGE', pd.Grouper(key='DATE', freq='M')])['PART'].sum().reset_index()

# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_part_ev_age.pivot_table(index='CAMP', columns='AGE', values='PART', fill_value=0)

# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))

# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)

# 각 연령대별로 누적 값 추가
for age in pivoted_data.columns:
    plt.bar(pivoted_data.index, pivoted_data[age], bottom=bottom_values, label=age)
    bottom_values += pivoted_data[age]

# 그래프 꾸미기
plt.title('캠페인-연령대별 참여자수')  # 제목 추가
plt.xlabel('캠페인')  # x축 라벨 추가
plt.ylabel('누적 참여자수')  # y축 라벨 추가
plt.legend(title='연령대', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10)  # 범례 설정
plt.xticks(rotation=45)  # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1])  # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show()  # 그래프 출력

 


시각화 작업
성별 데이터 분석

 

이번에는 성별 데이터를 이용한 데이터 시각화를 진행해 본다.

- 각 지역의 성별별 방문자수 누적막대그래프

# 데이터 집계 및 병합
off_df_gender = off_df.groupby(['성별', '날짜', '지역']).agg({'방문자수': 'sum', '참여자수': 'sum'}).reset_index()

# 컬럼 이름 변경
off_df_gender.rename(columns={'지역': 'CITY', '방문자수': 'VISITORS', '참여자수': 'PART', '날짜': 'DATE', '성별': 'GENDER'}, inplace=True)

# 날짜를 datetime으로 형변환
off_df_gender['DATE'] = pd.to_datetime(off_df_gender['DATE'])

# 참여율 칼럼 추가
off_df_gender['P_Ratio'] = (off_df_gender['PART'] / off_df_gender['VISITORS']) * 100

# 'DATE'를 월 단위로 그룹화하고 각 지역별 방문자 수를 합산
monthly_visit_gender = off_df_gender.groupby(['CITY', 'GENDER', pd.Grouper(key='DATE', freq='M')])['VISITORS'].sum().reset_index()

# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_visit_gender.pivot_table(index='CITY', columns='GENDER', values='VISITORS', fill_value=0)

# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))

# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)

# 각 연령대별로 누적 값 추가
for gender in pivoted_data.columns:
    plt.bar(pivoted_data.index, pivoted_data[gender], bottom=bottom_values, label=gender)
    bottom_values += pivoted_data[gender]

# 그래프 꾸미기
plt.title('성별별 방문자수')  # 제목 추가
plt.xlabel('지역')  # x축 라벨 추가
plt.ylabel('누적 방문자수')  # y축 라벨 추가
plt.legend(title='성별', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10)  # 범례 설정
plt.xticks(rotation=45)  # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1])  # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show()  # 그래프 출력

 

- 각 지역의 성별별 참여자수 누적막대그래프

# 'DATE'를 월 단위로 그룹화하고 각 지역별 참여자 수를 합산
monthly_part_gender = off_df_gender.groupby(['CITY', 'GENDER', pd.Grouper(key='DATE', freq='M')])['PART'].sum().reset_index()

# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_part_gender.pivot_table(index='CITY', columns='GENDER', values='PART', fill_value=0)

# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))

# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)

# 각 연령대별로 누적 값 추가
for gender in pivoted_data.columns:
    plt.bar(pivoted_data.index, pivoted_data[gender], bottom=bottom_values, label=gender)
    bottom_values += pivoted_data[gender]

# 그래프 꾸미기
plt.title('성별별 참여자수')  # 제목 추가
plt.xlabel('지역')  # x축 라벨 추가
plt.ylabel('누적 참여자수')  # y축 라벨 추가
plt.legend(title='성별', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10)  # 범례 설정
plt.xticks(rotation=45)  # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1])  # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show()  # 그래프 출력

- 월간 성별별 방문자수 라인 차트

# 시각화
plt.figure(figsize=(12, 9))
sns.lineplot(data=monthly_visit_gender, x='DATE', y='VISITORS', hue='GENDER', palette='Set1')

# 그래프 꾸미기
plt.legend(loc='upper center', ncol=4, bbox_to_anchor=(0.5, 1))
plt.title('월간 성별별 방문자수')
plt.xlabel('날짜')
plt.ylabel('수')
plt.xticks(rotation=45)
plt.grid(True)
plt.tight_layout()
plt.show()

 

 

- 월간 성별별 참여자수 라인 차트

# 시각화
plt.figure(figsize=(12, 9))
sns.lineplot(data=monthly_part_gender, x='DATE', y='PART', hue='GENDER', palette='Set2')

# 그래프 꾸미기
plt.legend(loc='upper center', ncol=4, bbox_to_anchor=(0.5, 1))
plt.title('월간 성별별 참여자수')
plt.xlabel('날짜')
plt.ylabel('수')
plt.xticks(rotation=45)
plt.grid(True)
plt.tight_layout()
plt.show()

 

 

- 각 성별의 캠페인 방문자수 누적 막대그래프

# 데이터 집계 및 병합
off_df_ev_gender = off_df.groupby(['성별', '날짜', '이벤트 종류']).agg({'방문자수': 'sum', '참여자수': 'sum'}).reset_index()

# 컬럼 이름 변경
off_df_ev_gender.rename(columns={'이벤트 종류': 'CAMP', '방문자수': 'VISITORS', '참여자수': 'PART', '날짜': 'DATE', '성별': 'GENDER'}, inplace=True)

# 날짜를 datetime으로 형변환
off_df_ev_gender['DATE'] = pd.to_datetime(off_df_ev_gender['DATE'])

# 참여율 칼럼 추가
off_df_ev_gender['P_Ratio'] = (off_df_ev_gender['PART'] / off_df_ev_gender['VISITORS']) * 100

# 'DATE'를 월 단위로 그룹화하고 각 캠페인별 참여자 수를 합산
monthly_visit_ev_gender = off_df_ev_gender.groupby(['CAMP', 'GENDER', pd.Grouper(key='DATE', freq='M')])['VISITORS'].sum().reset_index()

# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_visit_ev_gender.pivot_table(index='CAMP', columns='GENDER', values='VISITORS', fill_value=0)

# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))

# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)

# 각 연령대별로 누적 값 추가
for gender in pivoted_data.columns:
    plt.bar(pivoted_data.index, pivoted_data[gender], bottom=bottom_values, label=gender)
    bottom_values += pivoted_data[gender]

# 그래프 꾸미기
plt.title('캠페인-성별별 방문자수')  # 제목 추가
plt.xlabel('캠페인')  # x축 라벨 추가
plt.ylabel('누적 방문자수')  # y축 라벨 추가
plt.legend(title='성별', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10)  # 범례 설정
plt.xticks(rotation=45)  # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1])  # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show()  # 그래프 출력

 

 

- 각 성별의 캠페인 참여자수 누적 막대그래프

# 'DATE'를 월 단위로 그룹화하고 각 캠페인별 참여자 수를 합산
monthly_part_ev_gender = off_df_ev_gender.groupby(['CAMP', 'GENDER', pd.Grouper(key='DATE', freq='M')])['PART'].sum().reset_index()

# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_part_ev_gender.pivot_table(index='CAMP', columns='GENDER', values='PART', fill_value=0)

# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))

# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)

# 각 연령대별로 누적 값 추가
for gender in pivoted_data.columns:
    plt.bar(pivoted_data.index, pivoted_data[gender], bottom=bottom_values, label=gender)
    bottom_values += pivoted_data[gender]

# 그래프 꾸미기
plt.title('캠페인-성별별 참여자수')  # 제목 추가
plt.xlabel('캠페인')  # x축 라벨 추가
plt.ylabel('누적 참여자수')  # y축 라벨 추가
plt.legend(title='성별', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10)  # 범례 설정
plt.xticks(rotation=45)  # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1])  # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show()  # 그래프 출력

 

지금까지 오프라인 캠페인 데이터 관련 변수들을 가지고 데이터분석 시각화 작업을 진행해 보았다.

아무래도 실제 데이터가 아닌 가상 데이터로 진행하다보니, 데이터가 큰 차이 없이 균등하다. 물론, 실제로도 이러한 상황이 진행될 수 있으므로, 굳이 데이터를 인위적으로 조작할 필요는 없을 것으로 보인다. (현재 데이터를 시각화해보는 게 더 큰 목적이므로)

 

물론, 날짜 데이터가 있기 때문에 이를 토대로 월별이 아닌, 요일별 데이터로 나눠 분석을 해볼 수도 있고, 더 다양한 분석 기법이 있다. 

# 데이터 집계 및 병합
off_df_day = off_df.groupby(['성별', '날짜', '이벤트 종류']).agg({'방문자수': 'sum', '참여자수': 'sum'}).reset_index()

# 컬럼 이름 변경
off_df_day.rename(columns={'날짜': 'DATE', '이벤트 종류': 'CAMP', '성별': 'GENDER', 
                            '방문자수': 'VISITORS', '참여자수': 'PART'}, inplace=True)

# 데이터의 날짜를 날짜 데이터로 형변환
off_df_day['DATE'] = pd.to_datetime(off_df_day['DATE'])

# 요일 정보 추가
off_df_day['DAY_OF_WEEK'] = off_df_day['DATE'].dt.day_name()  # 요일 이름 추가

# 'DAY_OF_WEEK'와 '이벤트 종류', '성별'로 그룹화하고 참여자 수 합산
day_visit_ev_gender = off_df_day.groupby(['CAMP', 'GENDER', 'DAY_OF_WEEK'])['VISITORS'].sum().reset_index()

# 요일 순서 정렬
day_order = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
day_visit_ev_gender['DAY_OF_WEEK'] = pd.Categorical(day_visit_ev_gender['DAY_OF_WEEK'], categories=day_order, ordered=True)

# 데이터를 요일별로 정렬
day_visit_ev_gender = day_visit_ev_gender.sort_values(by='DAY_OF_WEEK').reset_index(drop=True)

# 시각화
plt.figure(figsize=(12, 9))
sns.lineplot(data=day_visit_ev_gender, x='DAY_OF_WEEK', y='VISITORS', hue='GENDER', palette='Set1')

# 그래프 꾸미기
plt.legend(loc='upper center', ncol=4, bbox_to_anchor=(0.5, 1))
plt.title('요일-성별별 방문자수')
plt.xlabel('요일')
plt.ylabel('수')
plt.xticks()
plt.grid(True)
plt.tight_layout()
plt.show()

# 시각화
plt.figure(figsize=(10, 5))
sns.barplot(data=day_visit_ev_gender, x='DAY_OF_WEEK', y='VISITORS', hue='GENDER', palette='Set2')

# 그래프 꾸미기
plt.legend(loc='upper center', ncol=4, bbox_to_anchor=(0.5, 1))
plt.title('요일-성별별 방문자수')
plt.xlabel('요일')
plt.ylabel('수')
plt.xticks()
plt.grid(True)
plt.tight_layout()
plt.show()

 

다음에는 데이터를 토대로 머신러닝 작업을 진행해 본다.


다음 내용

 

[파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 5

이전 내용 [파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 4이전 내용 [파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 3이전 내용 [파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 2

puppy-foot-it.tistory.com

 

 

728x90
반응형