-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbaseline_visualisation.py
172 lines (141 loc) · 8.07 KB
/
baseline_visualisation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import math
import tkinter as tk
from tkinter import filedialog
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import os
import numpy as np
class CSVViewer:
def __init__(self, root):
self.root = root
self.root.title("CSV Viewer and Graph Plotter")
# Индекс текущей строки в DataFrame
self.current_row = 0
# Основной DataFrame (после чтения CSV)
self.data = None
# Директория, где будут храниться текстовые файлы (с UUID именами)
self.data_dir = None
# Инициализация пользовательского интерфейса
self.init_ui()
def init_ui(self):
self.frame = tk.Frame(self.root)
self.frame.pack(fill=tk.BOTH, expand=True)
# Фрейм для области с графиком
self.canvas_frame = tk.Frame(self.frame)
self.canvas_frame.pack(fill=tk.BOTH, expand=True)
# Создаем фигуру matplotlib и холст, встраиваем их в интерфейс
self.figure, self.ax = plt.subplots(figsize=(6, 6))
self.canvas = FigureCanvasTkAgg(self.figure, master=self.canvas_frame)
self.canvas_widget = self.canvas.get_tk_widget()
self.canvas_widget.pack(fill=tk.BOTH, expand=True)
# Фрейм для кнопок управления
self.controls_frame = tk.Frame(self.frame)
self.controls_frame.pack()
self.prev_button = tk.Button(self.controls_frame, text="< Previous", command=self.show_previous_row)
self.prev_button.grid(row=0, column=0)
self.next_button = tk.Button(self.controls_frame, text="Next >", command=self.show_next_row)
self.next_button.grid(row=0, column=1)
self.open_button = tk.Button(self.controls_frame, text="Open CSV", command=self.open_csv)
self.open_button.grid(row=0, column=2)
def open_csv(self):
file_path = filedialog.askopenfilename(filetypes=[("CSV Files", "*.csv")])
if not file_path:
return
try:
# Считаем CSV-файл. Важно подставить правильную кодировку и разделитель.
self.data = pd.read_csv(file_path, sep=';', encoding='windows-1251')
# Определяем директорию "data", где будут лежать файлы с именами UUID
self.data_dir = os.path.join(os.path.dirname(file_path), "data")
# Сбрасываем индекс текущей строки
self.current_row = 0
# Отображаем данные по первой строке
self.show_current_row()
except Exception as e:
print(f"Error loading file: {e}")
def load_data_file(self, uuid):
"""
Загружает содержимое файла с данными на основе UUID (имени файла).
Предполагается, что файлы лежат в self.data_dir.
Возвращает текст (str) или None, если не удалось прочитать.
"""
if not self.data_dir:
return None
file_path = os.path.join(self.data_dir, uuid)
if not os.path.exists(file_path):
return None
try:
with open(file_path, 'r', encoding='utf-8') as file:
content = file.read()
return content
except Exception as e:
return None
def show_current_row(self):
if self.data is not None and not self.data.empty:
# Получаем UUID из первой колонки (0-й индекс) текущей строки
uuid = self.data.iloc[self.current_row, 0]
file_content = self.load_data_file(uuid)
if file_content is not None:
try:
# Разделяем файл с данными построчно и по табуляции
rows = [line.split('\t') for line in file_content.strip().split('\n')]
data = pd.DataFrame(rows, columns=['x', 'y1', 'y2'], dtype=float)
# Очищаем предыдущий график
self.ax.clear()
# Строим точки y1 и y2 на логарифмических осях
self.ax.loglog(data['x'], data['y1'], 'o', label='Series 1')
self.ax.loglog(data['x'], data['y2'], 'o', label='Series 2')
# Рисуем линии признаков течения вида y = 10^(k*log10(x) + b)
# k_values = {колонка в CSV: k-коэффициент}
# смысл k-коэффициентов и их привязка к признакам обозначена в приложении 2
k_values = {11: 1, 12: 0, 13: 0.5, 14: 0.25, 15: -0.5}
colors = ['green', 'red', 'blue', 'purple', 'orange']
x_range = data['x'].astype(float)
for (col, k), color in zip(k_values.items(), colors):
# Проверяем, чтобы колонка col не выходила за границы df
if col < len(self.data.columns):
b_value = self.data.iloc[self.current_row, col]
# Если в CSV есть валидное число, используем его
if pd.notna(b_value):
b_value = float(b_value)
# Формируем массив y_line
y_line = 10 ** (k * np.log10(x_range) + b_value)
self.ax.plot(x_range, y_line, label=f'Line (k={k}, b={b_value})', color=color)
# Вертикальные (пунктирные) линии по определённым колонкам
for col, label, color in zip([16, 17], ["P constant", "Impermeable"], ["blue", "red"]):
if col < len(self.data.columns):
x_value = self.data.iloc[self.current_row, col]
if pd.notna(x_value):
x_value = float(x_value)
y_min, y_max = data[['y1', 'y2']].min().min(), data[['y1', 'y2']].max().max()
self.ax.vlines(x=x_value,
ymin=y_min,
ymax=y_max,
linestyles='dashed',
color=color,
label=f'{label} (x={x_value})')
# Настройки заголовков и легенды
self.ax.set_title(f"Data for UUID: {uuid}")
self.ax.set_xlabel("X (log scale)")
self.ax.set_ylabel("Y (log scale)")
self.ax.set_aspect('equal', adjustable='datalim')
self.ax.legend()
# Отрисовываем график на холсте
if self.canvas:
self.canvas.draw()
else:
raise AttributeError("Canvas object is not initialized.")
except Exception as e:
print(f"Error plotting data for row {self.current_row}: {e}")
def show_previous_row(self):
if self.data is not None and self.current_row > 0:
self.current_row -= 1
self.show_current_row()
def show_next_row(self):
if self.data is not None and self.current_row < len(self.data) - 1:
self.current_row += 1
self.show_current_row()
if __name__ == "__main__":
root = tk.Tk()
app = CSVViewer(root)
root.mainloop()