자 그래서 오늘은 부동산 변동률 계산 마무리작업, 분기를 이전하기 전과 후로 나눈 데이터 정리를 진행하고 나머지는 시간 남으면 진행하자.
def split_data_by_date(data):
before_sep = [] # 2020년 9월 이전 데이터
after_sep = [] # 2020년 10월 이후 데이터
for record in data.get('row', []):
# "2017년 1월"과 같은 형식의 날짜 문자열을 "2017-01-01" 형식으로 변환
date_str = record.get("WRTTIME_DESC")
try:
# "yyyy년 mm월" 형태에서 "yyyy-mm-01"로 변환
date_obj = datetime.strptime(date_str + " 1일", "%Y년 %m월 %d일")
except ValueError:
continue # 날짜 형식이 맞지 않으면 skip
# 2020년 9월 이전 데이터와 이후 데이터로 분리
if date_obj < datetime(2020, 10, 1): # 2020년 9월 이전
before_sep.append(record)
else: # 2020년 10월 이후
after_sep.append(record)
return before_sep, after_sep
일단 데이터의 날짜 분리 함수 추가해줬고,
계산 로직을 짜고 있는데, 이걸 날짜를 저렇게 나눠서 하니까 분기로 나누기도 불편하고 로직이 상당히 복잡해져서 시계열 변동률 계산 방식을 도입해서 날짜를 나누지 않고 사람이 보고 판단할 수 있게 하는편이 좋을 것 같다고 판단되어서 그렇게 방향을 잡고 로직을 새로 짰음.

그래서 이런 결과를 얻어냈음.
이제는 수도권과 전국 기준으로도 결과가 잘 나오는지 확인하고 그래프로 그려주면 될 것 같음.
여튼 일단은 결과를 볼 수 있으니 결과를 취합해보자면
| 지역 | 발표 전 평균 변동률 | 발표 후 급등 변동률 | 조정 국면 변동률 | 최근 변동률 |
|---|---|---|---|---|
| 전국 | +0.5% | +3.5% | -3.5% | +0.4% |
| 수도권 | +1.5% | +4.0% | -3.5% | +1.0% |
| 세종 | +2.0% | +8.0% | -6.0% | +0.5% |
이렇게 뽑아볼 수 있다.
세종이 발표 직후에서 큰 이득을 봤지만 이후 조정을 심하게 맞은 것 같다.
아무래도 사회적, 정치적 측면의 영향을 많이 받은게 아닐까 싶다.
여튼간에 이제는 그래프로 표기할 코드 작성을 하면 될 것 같다.

오케이!!!!
그래프까지 뽑아냈음.
어떻게 했냐면,
@visualization_bp.route('/visualize', methods=['POST'])
def visualize_change_rate():
try:
# 클라이언트로부터 JSON 데이터를 POST 요청으로 받음
request_data = request.get_json()
print("DEBUG: Received request data:", request_data)
change_rate_data = request_data.get("change_rate", {})
region = request_data.get("region", "Unknown").capitalize() # region 값을 확인하고 처리
print("DEBUG: Parsed change rate data:", change_rate_data)
# 데이터 유효성 검사
if not change_rate_data:
print("DEBUG: Change rate data is missing or empty")
return jsonify({"error": "Change rate data is missing or invalid"}), 400
# 데이터 추출
quarters = list(change_rate_data.keys())
change_rates = [entry.get("Change Rate") for entry in change_rate_data.values()]
current_avg = [entry.get("Current Avg") for entry in change_rate_data.values()]
print("DEBUG: Quarters:", quarters) # 디버깅 추가
print("DEBUG: Change Rates:", change_rates) # 디버깅 추가
print("DEBUG: Current Averages:", current_avg) # 디버깅 추가
# 데이터 유효성 확인
if not quarters or not any(change_rates) or not any(current_avg):
print("DEBUG: Invalid or empty data for plotting") # 디버깅 추가
return jsonify({"error": "No valid data to visualize"}), 400
# 변동률 그래프 생성
fig1, ax1 = plt.subplots(figsize=(12, 6))
ax1.plot(quarters, change_rates, marker='o', label='Change Rate (%)')
ax1.axhline(y=0, color='gray', linestyle='--', linewidth=0.8, label='Baseline (0%)')
ax1.set_title(f"Quarterly Change Rate (%) - {region}", fontsize=14) # region 값 사용
ax1.set_xlabel('Quarter', fontsize=12)
ax1.set_ylabel('Change Rate (%)', fontsize=12)
ax1.legend()
ax1.grid(True)
plt.xticks(rotation=45)
# 이미지를 메모리 버퍼에 저장
img1 = io.BytesIO()
plt.tight_layout()
plt.savefig(img1, format='png')
img1.seek(0)
change_rate_img = base64.b64encode(img1.getvalue()).decode('utf8')
plt.close(fig1)
# 평균값 그래프 생성
fig2, ax2 = plt.subplots(figsize=(12, 6))
ax2.plot(quarters, current_avg, marker='o', color='orange', label='Average Value')
ax2.set_title(f"Quarterly Average Values - {region}", fontsize=14) # region 값 사용
ax2.set_xlabel('Quarter', fontsize=12)
ax2.set_ylabel('Average Value', fontsize=12)
ax2.legend()
ax2.grid(True)
plt.xticks(rotation=45)
# 이미지를 메모리 버퍼에 저장
img2 = io.BytesIO()
plt.tight_layout()
plt.savefig(img2, format='png')
img2.seek(0)
average_value_img = base64.b64encode(img2.getvalue()).decode('utf8')
plt.close(fig2)
# JSON 응답 생성
return jsonify({
"region": region,
"change_rate_image": f"data:image/png;base64,{change_rate_img}",
"average_value_image": f"data:image/png;base64,{average_value_img}"
})
except Exception as e:
print(f"DEBUG: Visualization Error: {e}") # 디버깅 추가
return jsonify({"error": "Failed to generate visualization", "details": str(e)}), 500
@real_estate_bp.route('/full-visualization', methods=['GET'])
def full_visualization():
region = request.args.get('region', 'nationwide')
property_type = request.args.get('type', 'apartment')
# Step 1: /change-rate 호출
change_rate_response = requests.get(
"http://127.0.0.1:5000/api/real-estate/change-rate",
params={"region": region, "type": property_type}
)
if change_rate_response.status_code != 200:
return jsonify({"error": "Failed to fetch change rate data"}), 500
change_rate_data = change_rate_response.json().get('change_rate', {})
# Step 2: /visualize 호출
visualization_response = requests.post(
"http://127.0.0.1:5000/api/visualization/visualize",
json={
"region": region,
"change_rate": change_rate_data
}
)
if visualization_response.status_code != 200:
return jsonify({"error": "Failed to generate visualization"}), 500
# 이미지 데이터를 템플릿에 전달하여 HTML로 렌더링
return render_template('visualization.html',
change_rate_image=visualization_response.json().get('change_rate_image'),
average_value_image=visualization_response.json().get('average_value_image'))
이렇게 포스트 엔드포인트랑 겟이랑 합쳐서 했음.
http://127.0.0.1:5000/api/real-estate/full-visualization?region=nationwide&type=apartment 요청 url 이 전국이고 아파트 값이니까 그에 대한 그래프가 출력된거고,
이걸 이제 세종이랑 housing으로 요청하게 된다면..

아까랑은 다른 그래프를 뱉어냄.
이러면 이제 그래프 이미지까지 확보 완료.
다음 포스팅으로 이제 인구이동률을 사용해서 뭔가 해보자고.