|
import matplotlib.pyplot as plt
|
|
from LLM_openai import client, expense_classifier
|
|
import datetime
|
|
import base64
|
|
from io import BytesIO
|
|
import re
|
|
import json
|
|
import matplotlib.dates as mdates
|
|
|
|
import pandas as pd
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
|
|
|
def create_plot(x, y):
|
|
|
|
fig, ax = plt.subplots(figsize=(10, 6), facecolor='#2E3440')
|
|
ax.set_facecolor('#2E3440')
|
|
|
|
|
|
ax.plot(x, y, marker='o', color='#88C0D0', linewidth=2, markersize=8, label='Expenses')
|
|
|
|
|
|
last_labeled_y = y.iloc[0]
|
|
indices_to_label = [0]
|
|
|
|
|
|
for i in range(1, len(y)):
|
|
if abs(y.iloc[i] - last_labeled_y) >= 15:
|
|
indices_to_label.append(i)
|
|
last_labeled_y = y.iloc[i]
|
|
|
|
|
|
if len(y) - 1 not in indices_to_label:
|
|
indices_to_label.append(len(y) - 1)
|
|
|
|
|
|
for i in indices_to_label:
|
|
ax.text(x.iloc[i], y.iloc[i], f'{y.iloc[i]:.1f}', fontsize=10, color='#ECEFF4',
|
|
ha='left', va='bottom', bbox=dict(facecolor='#3B4252', alpha=0.8, edgecolor='none'))
|
|
|
|
|
|
ax.set_xlabel('Money', fontsize=12, color='#ECEFF4')
|
|
ax.set_ylabel('Expenses', fontsize=12, color='#ECEFF4')
|
|
ax.set_title('Daily Expenses', fontsize=14, color='#ECEFF4', pad=20)
|
|
|
|
|
|
ax.tick_params(axis='both', colors='#ECEFF4')
|
|
ax.set_xticks(x[::5])
|
|
ax.set_xticklabels(x[::5], rotation=45, ha='right', color='#ECEFF4')
|
|
ax.grid(color='#4C566A', linestyle='--', linewidth=0.5, alpha=0.7)
|
|
|
|
|
|
|
|
|
|
|
|
plt.tight_layout()
|
|
return fig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
def create_barplot(x, y, xlabel, ylabel, title):
|
|
|
|
fig, ax = plt.subplots(figsize=(10, 6), facecolor='#2E3440')
|
|
ax.set_facecolor('#2E3440')
|
|
|
|
|
|
bars = ax.bar(x, y, color='#88C0D0', edgecolor='#4C566A', linewidth=1)
|
|
|
|
|
|
for i in range(len(x)):
|
|
ax.text(
|
|
x[i], y[i], f'{y[i]:.2f}',
|
|
fontsize=10, color='#ECEFF4',
|
|
ha='center', va='bottom',
|
|
bbox=dict(facecolor='#3B4252', alpha=0.8, edgecolor='none')
|
|
)
|
|
|
|
|
|
ax.set_xlabel(xlabel, fontsize=12, color='#ECEFF4')
|
|
ax.set_ylabel(ylabel, fontsize=12, color='#ECEFF4')
|
|
ax.set_title(title, fontsize=14, color='#ECEFF4', pad=20)
|
|
|
|
|
|
ax.tick_params(axis='both', colors='#ECEFF4')
|
|
plt.xticks(rotation=30, color='#ECEFF4')
|
|
ax.grid(color='#4C566A', linestyle='--', linewidth=0.5, alpha=0.7, axis='y')
|
|
|
|
|
|
for spine in ax.spines.values():
|
|
spine.set_visible(False)
|
|
|
|
|
|
plt.tight_layout()
|
|
return fig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def pil_to_base64(pil_img):
|
|
img_buffer = BytesIO()
|
|
pil_img.save(img_buffer, format='JPEG')
|
|
byte_data = img_buffer.getvalue()
|
|
base64_str = base64.b64encode(byte_data).decode("utf-8")
|
|
return base64_str
|
|
|
|
def js_to_prefere_the_back_camera_of_mobilephones():
|
|
custom_html = """
|
|
<script>
|
|
const originalGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);
|
|
|
|
navigator.mediaDevices.getUserMedia = (constraints) => {
|
|
if (!constraints.video.facingMode) {
|
|
constraints.video.facingMode = {ideal: "environment"};
|
|
}
|
|
return originalGetUserMedia(constraints);
|
|
};
|
|
</script>
|
|
"""
|
|
return custom_html
|
|
|
|
def result_cleaner(text):
|
|
pattern = r'\{[^}]*\}'
|
|
match = re.search(pattern, text)
|
|
match_string=match[0]
|
|
json_dict=json.loads(match_string)
|
|
|
|
|
|
return json_dict |