Advertisement
Guest User

Untitled

a guest
Dec 11th, 2018
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.35 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Mon Dec 10 20:35:34 2018
  4.  
  5. @author: Jaymon
  6. """
  7.  
  8. import tkinter as tk # python 3
  9. from tkinter import font as tkfont # python 3]
  10. from tkinter import filedialog
  11. from matplotlib.widgets import Slider
  12. from tkinter import *
  13.  
  14. import pandas as pd
  15. import numpy as np
  16.  
  17. try:
  18. import pygraphviz
  19. from networkx.drawing.nx_agraph import graphviz_layout
  20. except ImportError:
  21. try:
  22. import pydot
  23. from networkx.drawing.nx_pydot import graphviz_layout
  24. except ImportError:
  25. raise ImportError("This script needs Graphviz and either "
  26. "PyGraphviz or pydot")
  27. import matplotlib
  28. import matplotlib.cm as cm
  29. from matplotlib.colors import Normalize
  30. import networkx as nx
  31.  
  32. # Import backend of matplotlib
  33. matplotlib.use("TkAgg")
  34. from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
  35.  
  36. from matplotlib.figure import Figure
  37.  
  38. hierarchyfile = 'profile_semantic_trafo_final_hierarchy.txt'
  39. datafile = 'profile_semantic_trafo_final.txt'
  40. df = pd.read_table(datafile, delim_whitespace=True)
  41.  
  42.  
  43. def remove_substring(string, array):
  44. """
  45. Input:
  46. string = string to be removed
  47. arrays = array of arrays which contain strings
  48. Output: cleaned array
  49. """
  50. i = 0
  51. while i < len(array):
  52. array[i] = array[i].replace(string, '')
  53. i = i + 1
  54. return array
  55.  
  56.  
  57. def range_aggregate(sdf, col, size):
  58. """
  59. Aggregated the values in col to bins of the width of size.
  60.  
  61. Input
  62. ----------
  63. df = Dataframe time value in col
  64. col = Column with time value
  65. size = the width of the filter
  66.  
  67. Output
  68. ----------
  69. Dataframe object
  70. """
  71. df = sdf
  72. times = df[col].unique()
  73. if size < len(times) / 2 and size > 1:
  74. aggregated = {}
  75. i = 0
  76. time = 0
  77. while time < len(times):
  78. if i == 0:
  79. try:
  80. name = str(times[time]) + '-' + str(times[size + time - 1])
  81. except:
  82. name = str(times[time]) + '-' + str(times[-1])
  83. aggregated[str(times[time])] = name
  84. i = i + 1
  85. time = time + 1
  86. if i == size:
  87. i = 0
  88. df[col + '_grouped'] = df[col].apply(str)
  89. df[col + '_grouped'] = df[col + '_grouped'].map(aggregated)
  90. else:
  91. sdf[col] = sdf[col].apply(str)
  92. return df
  93.  
  94.  
  95. def hierarchy_aggregate(sdf, cols, depth, hierarchy_file):
  96. """
  97. Turns all of the columns in cols into hierarchy strings trimed to a
  98. maximum depth.
  99.  
  100. Input
  101. ----------
  102. df = Dataframe
  103. cols = Array with column values
  104. depth = depth of hierarchy
  105.  
  106. Output
  107. ----------
  108. DataFrame with an aditional col for each col in cols
  109. """
  110. df = sdf
  111. # Import hierarchy names
  112. hierarchy = open(hierarchy_file)
  113. filenames = []
  114. for line in hierarchy:
  115. line = line.rstrip()
  116. filenames.append(line)
  117. hierarchy.close()
  118.  
  119. # Clean files
  120. minval = min([min(df['start']), min(df['target'])])
  121. i = 0
  122. while i < minval - 1:
  123. strlen = 1
  124. line = filenames[i]
  125. while string_in_arrays(line[:strlen], filenames):
  126. strlen = strlen + 1
  127. if strlen > len(line):
  128. break
  129. i = i + 1
  130. filenames = remove_substring(filenames[i][:strlen - 1], filenames)
  131.  
  132. # Transfer strings to lists
  133. arr = 0
  134. while arr < len(filenames):
  135. if not filenames[arr] == []:
  136. filenames[arr] = filenames[arr].strip('/')
  137. filenames[arr] = filenames[arr].split('/')
  138. # Cuts off unrequested detail
  139. if len(filenames[arr]) > depth:
  140. filenames[arr] = filenames[arr][:depth]
  141. arr = arr + 1
  142.  
  143. # Adds file lists to dictionary
  144. index = 0
  145. names = {}
  146. number = 0
  147. numbers = {}
  148. while index < len(filenames):
  149. names[index + 1] = filenames[index]
  150. index = index + 1
  151.  
  152. # Creates new columns for the arrays
  153. for col in cols:
  154. df[col + '_location'] = df[col].map(names)
  155. df[col + '_location'] = df[col + '_location'].apply(str)
  156. return df
  157.  
  158.  
  159. def string_in_arrays(string, array):
  160. """
  161. Input:
  162. string = string to be found
  163. arrays = array of arrays which contain strings
  164. Output: Bool, string in all the arrays
  165. """
  166. for str in array:
  167. if not string in str:
  168. return False
  169. return True
  170.  
  171.  
  172. def radialNodeLinkVis(G):
  173. pos = graphviz_layout(G, prog='twopi', args='')
  174. plt.figure(figsize=(8, 8))
  175. nx.draw(G, pos, node_size=20, alpha=0.5, node_color="blue", with_labels=False)
  176. plt.axis('equal')
  177. return (plt.show())
  178.  
  179.  
  180. class SampleApp(tk.Tk):
  181.  
  182. def __init__(self, *args, **kwargs):
  183. tk.Tk.__init__(self, *args, **kwargs)
  184.  
  185. self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
  186.  
  187. # the container is where we'll stack a bunch of frames
  188. # on top of each other, then the one we want visible
  189. # will be raised above the others
  190. container = tk.Frame(self)
  191. container.pack(side="top", fill="both", expand=True)
  192. container.grid_rowconfigure(0, weight=1)
  193. container.grid_columnconfigure(0, weight=1)
  194.  
  195. self.frames = {}
  196. for F in (StartPage, PageOne, PageTwo):
  197. page_name = F.__name__
  198. frame = F(parent=container, controller=self)
  199. self.frames[page_name] = frame
  200.  
  201. # put all of the pages in the same location;
  202. # the one on the top of the stacking order
  203. # will be the one that is visible.
  204. frame.grid(row=0, column=0, sticky="nsew")
  205.  
  206. self.show_frame("StartPage")
  207.  
  208. def show_frame(self, page_name):
  209. '''Show a frame for the given page name'''
  210. frame = self.frames[page_name]
  211. frame.tkraise()
  212.  
  213. def sel_df(self):
  214. # Select the txt file of the dataset
  215. self.path_df = filedialog.askopenfilename(initialdir="/", title
  216. ="Select file", filetypes
  217. =(("txt files", "*.txt"),
  218. ("all files", "*.*")))
  219. # Create df out of it and store it
  220. self.df = pd.read_table(self.path_df, delim_whitespace=True)
  221.  
  222. def sel_df_hier(self):
  223. # Select the txt file of the hierarchy dataset.
  224. self.path_df_hier = filedialog.askopenfilename(initialdir="/", title
  225. ="Select file", filetypes
  226. =(("txt files", "*.txt"),
  227. ("all files", "*.*")))
  228. # Create df out of it and store it
  229. self.df_hier = pd.read_table(self.path_df_hier, delim_whitespace=True)
  230.  
  231.  
  232. class StartPage(tk.Frame):
  233.  
  234. def __init__(self, parent, controller):
  235. tk.Frame.__init__(self, parent)
  236. self.controller = controller
  237. label = tk.Label(self, text="GUI group X", font=controller.title_font)
  238. label.pack(side="top", fill="x", pady=10)
  239.  
  240. button1 = tk.Button(self, text="Import main file",
  241. command=lambda: controller.sel_df())
  242. button2 = tk.Button(self, text="Import hierarchy file",
  243. command=lambda: controller.sel_df_hier())
  244. button3 = tk.Button(self, text="Adjacency matrix and Dynamic Graph",
  245. command=lambda: controller.show_frame("PageOne"))
  246. button4 = tk.Button(self, text="Exercise 7",
  247. command=lambda: controller.show_frame("PageTwo"))
  248.  
  249. button1.pack()
  250. button2.pack()
  251. button3.pack()
  252. button4.pack()
  253.  
  254.  
  255. class PageOne(tk.Frame):
  256.  
  257. def __init__(self, parent, controller):
  258. tk.Frame.__init__(self, parent)
  259. self.controller = controller
  260. label = tk.Label(self, text="Adjacency Matrix and Dynamic Graph", font=controller.title_font)
  261. label.pack(side="top", fill="x", pady=10)
  262. button = tk.Button(self, text="Go to the start page",
  263. command=lambda: controller.show_frame("StartPage"))
  264. button.pack()
  265.  
  266. #Label and entry for min time
  267. label_min_t = StringVar()
  268. label_min_t.set("Enter desired value for minimum time:")
  269. label_min_t_dir = Label(self, textvariable=label_min_t)
  270. label_min_t_dir.pack(side='left', fill="x", pady=10)
  271.  
  272. e_min_t = Entry(self, width=10)
  273. # Set place holder
  274. e_min_t.insert(END, "0")
  275. e_min_t.pack(side='left', fill="x", pady=10)
  276.  
  277. label_max_t = StringVar()
  278. label_max_t.set("Enter desired value for maximum time:")
  279. label_max_t = Label(self, textvariable=label_min_t)
  280. label_max_t.pack(side='left', fill="x", pady=10)
  281.  
  282. #Label and entry for max time
  283. e_max_t = Entry(self, width=10)
  284. # Set place holder
  285. e_max_t.insert(END, "300")
  286. e_max_t.pack(side='left', fill="x", pady=10)
  287.  
  288. button_update = tk.Button(self, text="Update",
  289. command=lambda: self.update(e_min_t.get(), e_max_t.get(),
  290. cmapvar.get()))
  291. button_update.pack(side='left', fill="x", pady=10)
  292.  
  293. label_cmap = StringVar()
  294. label_cmap.set("Select desired colormap:")
  295. label_cmap = Label(self, textvariable=label_cmap)
  296. label_cmap.pack(side="top", fill="x", pady=10)
  297.  
  298. cmapvar = StringVar()
  299. cmap_choices = {"YlOrRd", "Blues", "cubehelix_r", "gist_rainbow_r",
  300. "gist_stern_r", "plasma", "nipy_spectral_r"}
  301. cmapvar.set("RdY1Gn")
  302.  
  303. cmap_menu = OptionMenu(self, cmapvar, *cmap_choices)
  304. cmap_menu.pack(side="top")
  305.  
  306. self.print_graph(df, 'time', 'start', 'target', hierarchyfile, 1, 5, "cubehelix_r", weight='weight',
  307. min_time=1, max_time=300, min_weight=0, max_weight='max')
  308.  
  309. # Create canvas
  310. self.canvas = FigureCanvasTkAgg(self.fig, self)
  311. self.canvas.draw()
  312. self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
  313.  
  314. # Add standard-layout
  315. toolbar = NavigationToolbar2Tk(self.canvas, self)
  316. toolbar.update()
  317. self.canvas._tkcanvas.pack(side="top", fill="x", pady=10)
  318.  
  319. # Update the graph with user input values.
  320. def update(self, var_min_t, var_max_t, cmap):
  321. self.print_graph(df, 'time', 'start', 'target', hierarchyfile, 1, 5, cmap, weight='weight',
  322. min_time=int(var_min_t), max_time=int(var_max_t), min_weight=0, max_weight='max', a=self.a,)
  323. print('processed')
  324. self.canvas.draw()
  325. print('drawn')
  326.  
  327. def print_graph(self, sdf, time, start, target, hierarchy, width, depth, colormap, weight='weight',
  328. min_time='min', max_time='max', min_weight='min', max_weight='max', a=True):
  329. """
  330. Prints a dynamic graph visualisation by drawing the static graphs of each
  331. timeslot ontop of each other. Incorperates a range of filering and
  332. aggregation tools.
  333.  
  334. Input
  335. ----------
  336. sdf = DataFrame with dynamic graph data
  337. time = time column of sdf DataFrame
  338. start = vertex column of sdf DataFrame where edges start
  339. target = vertex column of sdf DataFrame where edges end
  340. hierarchy = file where the hierarchy is stored, linked to values of vertices
  341. width = width in time steps of the time
  342. depth = maximum depth of hierarchy values
  343. weight = weight column of sdf DataFrame, default = 'weight'
  344. min_time = minimum value of time, default = minimum of sdf[time]
  345. max_time = maximum value of time, default = maximum of sdf[time]
  346. min_weight = minimum value of weight, default = minimum of sdf[weight]
  347. max_weight = maximum value of weight, default = maximum of sdf[weight]
  348. colormap = chosen colormap
  349.  
  350.  
  351. Output
  352. ----------
  353. Returns a Figure object
  354.  
  355. """
  356.  
  357. # Filter Dataset
  358. sdf = sdf.copy()
  359. if min_time == 'min':
  360. min_list = sdf[time] >= sdf[time].min()
  361. else:
  362. min_list = sdf[time] >= min_time
  363. if max_time == 'max':
  364. max_list = sdf[time] <= sdf[time].max()
  365. else:
  366. max_list = sdf[time] <= max_time
  367. sdf = sdf[min_list & max_list]
  368.  
  369. # recycle the list names
  370. if min_weight == 'min':
  371. min_list = sdf[weight] >= sdf[weight].min()
  372. else:
  373. min_list = sdf[weight] >= min_weight
  374. if max_weight == 'max':
  375. max_list = sdf[weight] <= sdf[weight].max()
  376. else:
  377. max_list = sdf[time] <= max_weight
  378. sdf = sdf[min_list & max_list]
  379.  
  380. # Transform Weights
  381. sdf['weight'] = sdf['weight'].apply(np.log10)
  382. sdf = sdf[min_list & max_list]
  383.  
  384. # Aggregates dataset
  385. sdf = range_aggregate(sdf, time, width)
  386. sdf = hierarchy_aggregate(sdf, [start, target], depth, hierarchy)
  387.  
  388. # Set aggregated names
  389. time_agg = time + '_grouped'
  390. start_agg = start + '_location'
  391. target_agg = target + '_location'
  392. headers = sdf.dtypes.index
  393.  
  394. # Checks if aggregate columns exist
  395. if time_agg in headers:
  396. time = time_agg
  397. if start_agg in headers and target_agg in headers:
  398. start = start_agg
  399. target = target_agg
  400. print(len(sdf))
  401. sdf['freq'] = sdf.groupby([time, start, target])['weight'].transform('count')
  402.  
  403. print(len(sdf))
  404. # Setup variables for creating the graph
  405. times = sdf[time].unique()
  406. end = {}
  407. self.fig = Figure(figsize=(12, 8), dpi=100)
  408. if not a == True:
  409. a.clear()
  410. self.a = a
  411. else:
  412. self.fig = Figure(figsize=(12, 8), dpi=100)
  413. self.a = self.fig.add_subplot(111)
  414.  
  415. self.a.get_xaxis().set_visible(False)
  416. self.a.get_yaxis().set_visible(False)
  417. offset = 5
  418. i = 0
  419.  
  420. # Creates dict for the end location of lines
  421. while i < len(times):
  422. try:
  423. end[times[i]] = times[i + offset]
  424. except:
  425. end[times[i]] = 'end+' + str(i + offset - len(times))
  426. i = i + 1
  427.  
  428. norm = Normalize(vmin=sdf['weight'].min(), vmax=sdf['weight'].max())
  429. cmap = cm.get_cmap(name=colormap)
  430. m = cm.ScalarMappable(norm=norm, cmap=cmap)
  431.  
  432. # Plots every row in the dataframe to the plot
  433. for index, row in sdf.iterrows():
  434. x = [row[time], end[row[time]]]
  435. y = [row[start], row[target]]
  436. self.a.plot(x, y, alpha=0.3, c=m.to_rgba(row['weight']))
  437.  
  438.  
  439. class PageTwo(tk.Frame):
  440.  
  441. def __init__(self, parent, controller):
  442. tk.Frame.__init__(self, parent)
  443. self.controller = controller
  444. label = tk.Label(self, text="Exercise 7", font=controller.title_font)
  445. label.pack(side="top", fill="x", pady=10)
  446. button = tk.Button(self, text="Go to the start page",
  447. command=lambda: controller.show_frame("StartPage"))
  448. button.pack()
  449.  
  450.  
  451. if __name__ == "__main__":
  452. app = SampleApp()
  453. app.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement