파이썬 시각화로 성적 변화 비교 그래프 만들기: 점수 상승/하락 색상 구분
학생들의 중간고사와 기말고사 성적 변화를 숫자만으로 비교하는 것은 어려울 수 있습니다. 하지만 시각화를 활용하면 다음 그림과 같이 성적의 상승과 하락을 직관적으로 파악할 수 있죠.

이번 포스트에서는 파이썬의 matplotlib를 사용하여 중간고사와 기말고사 성적 변화 비교 그래프를 다음과 같은 특징이 있게 만들어 봅니다.
- 점수가 상승하면 초록색, 하락하면 빨간색으로 선과 텍스트를 표시합니다.
- 수직 점선을 추가해 시점별 성적 변화를 깔끔하게 구분합니다.
성적 변화 그래프란?
성적 변화 그래프는 특정 시점 간의 점수 변화를 보여주는 시각화입니다. 각 학생의 중간고사와 기말고사 점수를 선으로 연결하고, 점수 변화에 따라 색상을 다르게 표시해 데이터를 더욱 명확하게 표현합니다.
그래프 특징
- 빨간색: 점수가 하락한 경우
- 초록색: 점수가 상승한 경우
- 좌측과 우측에 이름과 점수를 표시해 직관적으로 이해할 수 있습니다.
파이썬 코드 예제
아래는 matplotlib를 활용해 성적 변화 그래프를 구현하는 코드입니다.
전체 코드
import matplotlib.pyplot as plt
# 학생 이름과 성적 데이터 설정
students = ['Tom', 'Richard', 'Anna', 'Emily', 'Grace']
midterm_scores = [75, 70, 65, 60, 45] # 중간고사 성적
final_scores = [55, 40, 75, 70, 65] # 기말고사 성적
# 그래프 생성 및 사이즈 설정
fig, ax = plt.subplots(figsize=(10, 6)) # 그래프 크기 설정
ax.set_title("Student Exam Scores", fontsize=15) # 그래프 제목 설정
# 중간고사 점수와 이름 표시 (좌측 - 수직 점선 왼쪽으로 간격 설정)
ax.scatter([1] * len(midterm_scores), midterm_scores, color='red', s=50, zorder=3)
for i, txt in enumerate(midterm_scores):
color = 'green' if final_scores[i] > midterm_scores[i] else 'red' # 성적 상승 시 초록, 하락 시 빨강
ax.text(0.75, midterm_scores[i], f"{students[i]} ({txt})", fontsize=10, color=color, va='center', ha='right') # 왼쪽에 이름과 점수 표시
# 기말고사 점수와 이름 표시 (우측 - 수직 점선 오른쪽으로 간격 설정)
ax.scatter([2] * len(final_scores), final_scores, color='green', s=50, zorder=3)
for i, txt in enumerate(final_scores):
color = 'green' if final_scores[i] > midterm_scores[i] else 'red' # 성적 상승 시 초록, 하락 시 빨강
ax.text(2.25, final_scores[i], f"{students[i]} ({txt})", fontsize=10, color=color, va='center', ha='left') # 오른쪽에 이름과 점수 표시
# 중간고사와 기말고사 점수를 연결하는 선 그리기
for i in range(len(students)):
color = 'green' if final_scores[i] > midterm_scores[i] else 'red' # 성적 상승 시 초록, 하락 시 빨강
ax.plot([1, 2], [midterm_scores[i], final_scores[i]], color=color, linewidth=2, zorder=2) # 두 점을 선으로 연결
# 수직 점선 추가 (중간고사와 기말고사 위치 강조)
ax.axvline(x=1, color='gray', linestyle='--', linewidth=1) # Midterm 수직 점선
ax.axvline(x=2, color='gray', linestyle='--', linewidth=1) # Final 수직 점선
# X축 설정
ax.set_xticks([1, 2])
ax.set_xticklabels(["Midterm", "Final"], fontsize=12, fontweight='bold') # x축 레이블 설정
# Y축과 눈금 제거
ax.yaxis.set_visible(False) # Y축 제거
ax.set_yticks([]) # Y축 눈금 제거
# 성적 변화 비교 그래프 테두리 제거
ax.spines['left'].set_visible(False) # 왼쪽 테두리 제거
ax.spines['right'].set_visible(False) # 오른쪽 테두리 제거
ax.spines['top'].set_visible(False) # 상단 테두리 제거
ax.spines['bottom'].set_visible(False) # 하단 테두리 제거
# 성적 변화 비교 그래프 출력
plt.show()코드 간략 설명

1. 데이터 설정
- 학생 이름과 중간고사, 기말고사 점수를 리스트에 저장합니다.
2. 중간고사/기말고사 점수 표시
- 중간고사: 점을
x=1에 찍고, 이름과 점수를 수직 점선의 왼쪽에 표시합니다. - 기말고사: 점을
x=2에 찍고, 이름과 점수를 수직 점선의 오른쪽에 표시합니다.
3. 점수 변화선 연결
plot()을 사용해 점수를 선으로 연결하고, 상승은 초록색, 하락은 빨간색으로 구분합니다.
4. 수직 점선 추가
ax.axvline()을 사용해 중간고사와 기말고사 위치를 강조합니다.
5. Y축과 불필요한 요소 제거
- Y축과 눈금을 제거해 깔끔한 그래프를 만듭니다.
결과 그래프 특징
- 왼쪽에는 중간고사 점수와 이름이 수직 점선에서 살짝 떨어진 곳에 표시됩니다.
- 오른쪽에는 기말고사 점수와 이름이 표시됩니다.
- 점수 상승은 초록색 선과 텍스트, 하락은 빨간색 선과 텍스트로 구분됩니다.
- 불필요한 Y축과 테두리를 제거해 그래프가 더 깔끔하고 세련된 형태로 표시됩니다.
활용 및 확장
이 시각화는 성적 변화뿐만 아니라 매출 데이터, 프로젝트 진행 상황 등 두 시점 간의 변화를 시각화하는 데 활용할 수 있습니다. 색상과 레이블 배치를 적절히 조정하면 더욱 직관적인 결과를 얻을 수 있습니다.
마무리
이제 파이썬을 활용해 중간고사와 기말고사 성적 변화를 한눈에 보여주는 그래프를 만들 수 있습니다. 코드를 직접 실행해 보고 여러분의 데이터에 맞게 응용해 보세요!
이번 성적 변화 비교 그래프처럼 독특한 형태의 파이썬 시각화 사례가 있는데, 수면 패턴 분석과 파이썬 시각화: 건강한 수면을 위한 데이터 활용법 포스트를 확인해보세요. 흥미로울꺼예요!
# 코드 상세해설
1. 라이브러리 불러오기
import matplotlib.pyplot as plt
- matplotlib.pyplot: 데이터 시각화를 위해 사용하는 파이썬 라이브러리입니다.
- 그래프를 그리는 모든 함수가 포함된 모듈입니다.
2. 학생 이름과 성적 데이터 설정
students = ['Tom', 'Richard', 'Anna', 'Emily', 'Grace'] midterm_scores = [75, 70, 65, 60, 45] # 중간고사 성적 final_scores = [55, 40, 75, 70, 65] # 기말고사 성적
- students: 각 학생의 이름 리스트입니다.
- midterm_scores: 학생들의 중간고사 성적입니다.
- final_scores: 학생들의 기말고사 성적입니다.
3. 그래프 생성 및 사이즈 설정
fig, ax = plt.subplots(figsize=(10, 6)) ax.set_title("Student Exam Scores", fontsize=15)
- plt.subplots(figsize=(10, 6)): 가로 10, 세로 6인 그래프 영역을 생성합니다.
- ax.set_title(): 그래프 상단에 제목을 설정합니다.
fontsize=15: 글자 크기를 15로 설정합니다.4. 중간고사 점수와 이름 표시
ax.scatter([1] * len(midterm_scores), midterm_scores, color='red', s=50, zorder=3)
- ax.scatter(): 점을 찍어 중간고사 점수를 시각화합니다.
[1] * len(midterm_scores): 모든 점을 x=1 위치에 표시합니다.midterm_scores: y축 위치를 각 학생의 중간고사 점수로 설정합니다.color='red': 점의 색상을 빨간색으로 설정합니다.s=50: 점의 크기를 50으로 설정합니다.zorder=3: 점이 선 위에 그려지도록 설정합니다.for i, txt in enumerate(midterm_scores): color = 'green' if final_scores[i] > midterm_scores[i] else 'red' ax.text(0.75, midterm_scores[i], f"{students[i]} ({txt})", fontsize=10, color=color, va='center', ha='right')
- for i, txt in enumerate(midterm_scores): 각 학생의 중간고사 점수와 이름을 반복해서 표시합니다.
- color 조건:
- 기말고사 점수가 중간고사보다 높으면 녹색, 그렇지 않으면 빨간색으로 표시합니다.
- ax.text(): 텍스트(학생 이름과 점수)를 점 왼쪽에 표시합니다.
0.75: 수직 점선(x=1)에서 왼쪽으로 떨어진 위치입니다.midterm_scores[i]: 텍스트의 y 위치를 각 학생의 점수에 맞춥니다.f"{students[i]} ({txt})": 학생 이름과 점수를 문자열로 표시합니다.ha='right': 텍스트를 오른쪽 정렬합니다.va='center': 텍스트를 점의 수직 중앙에 배치합니다.5. 기말고사 점수와 이름 표시
ax.scatter([2] * len(final_scores), final_scores, color='green', s=50, zorder=3)
- ax.scatter(): 점을 찍어 기말고사 점수를 시각화합니다.
[2] * len(final_scores): 모든 점을 x=2 위치에 표시합니다.final_scores: y축 위치를 각 학생의 기말고사 점수로 설정합니다.color='green': 점의 색상을 초록색으로 설정합니다.for i, txt in enumerate(final_scores): color = 'green' if final_scores[i] > midterm_scores[i] else 'red' ax.text(2.25, final_scores[i], f"{students[i]} ({txt})", fontsize=10, color=color, va='center', ha='left')
- for i, txt in enumerate(final_scores): 각 학생의 기말고사 점수와 이름을 반복해서 표시합니다.
- color 조건:
- 기말고사 점수가 중간고사보다 높으면 녹색, 그렇지 않으면 빨간색으로 표시합니다.
- ax.text(): 텍스트(학생 이름과 점수)를 점 오른쪽에 표시합니다.
2.25: 수직 점선(x=2)에서 오른쪽으로 떨어진 위치입니다.final_scores[i]: 텍스트의 y 위치를 각 학생의 점수에 맞춥니다.ha='left': 텍스트를 왼쪽 정렬합니다.va='center': 텍스트를 점의 수직 중앙에 배치합니다.6. 점수 변화선 연결
for i in range(len(students)): color = 'green' if final_scores[i] > midterm_scores[i] else 'red' ax.plot([1, 2], [midterm_scores[i], final_scores[i]], color=color, linewidth=2, zorder=2)
- for i in range(len(students)): 각 학생의 성적 변화를 선으로 연결합니다.
- color 조건: 점수 상승 시 녹색, 점수 하락 시 빨간색으로 설정합니다.
- ax.plot(): 두 점을 선으로 연결합니다.
[1, 2]: x축 위치 (중간고사 → 기말고사)[midterm_scores[i], final_scores[i]]: y축 위치를 중간고사와 기말고사 점수로 설정합니다.linewidth=2: 선의 두께를 2로 설정합니다.7. 수직 점선 추가
ax.axvline(x=1, color='gray', linestyle='--', linewidth=1) ax.axvline(x=2, color='gray', linestyle='--', linewidth=1)
- ax.axvline(): x축의 특정 위치에 수직 점선을 그립니다.
x=1: 중간고사 위치에 점선 추가x=2: 기말고사 위치에 점선 추가color='gray': 점선 색상을 회색으로 설정합니다.linestyle='--': 점선을 설정합니다.linewidth=1: 점선의 두께를 1로 설정합니다.8. X축 설정
ax.set_xticks([1, 2]) ax.set_xticklabels(["Midterm", "Final"], fontsize=12, fontweight='bold')
- set_xticks([1, 2]): x축에 눈금을 추가합니다.
- set_xticklabels(): 눈금 레이블을 “Midterm”과 “Final”로 설정합니다.
9. Y축 및 테두리 제거
ax.yaxis.set_visible(False) ax.set_yticks([]) ax.spines['left'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) ax.spines['bottom'].set_visible(False)
- Y축 제거:
ax.yaxis.set_visible(False): Y축을 보이지 않게 설정합니다.ax.set_yticks([]): Y축 눈금을 제거합니다.- 테두리 제거:
spines['left'].set_visible(False): 왼쪽 테두리 제거spines['right']: 오른쪽 테두리 제거spines['top']: 상단 테두리 제거spines['bottom']: 하단 테두리 제거10. 그래프 출력
plt.show()
- plt.show(): 그래프를 화면에 출력합니다.






