Advertisement
Guest User

Untitled

a guest
Dec 11th, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.91 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.  
  15. import pandas as pd
  16. import numpy as np
  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.  
  39.  
  40. hierarchyfile = 'profile_semantic_trafo_final_hierarchy.txt'
  41. datafile = 'profile_semantic_trafo_final.txt'
  42. df = pd.read_table(datafile, delim_whitespace=True)
  43.  
  44. def remove_substring(string, array):
  45. """
  46. Input:
  47. string = string to be removed
  48. arrays = array of arrays which contain strings
  49. Output: cleaned array
  50. """
  51. i = 0
  52. while i < len(array):
  53. array[i] = array[i].replace(string, '')
  54. i = i + 1
  55. return array
  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. return df
  91.  
  92.  
  93. def hierarchy_aggregate(sdf, cols, depth, hierarchy_file):
  94. """
  95. Turns all of the columns in cols into hierarchy strings trimed to a
  96. maximum depth.
  97.  
  98. Input
  99. ----------
  100. df = Dataframe
  101. cols = Array with column values
  102. depth = depth of hierarchy
  103.  
  104. Output
  105. ----------
  106. DataFrame with an aditional col for each col in cols
  107. """
  108. df = sdf
  109. # Import hierarchy names
  110. hierarchy = open(hierarchy_file)
  111. filenames = []
  112. for line in hierarchy:
  113. line = line.rstrip()
  114. filenames.append(line)
  115. hierarchy.close()
  116.  
  117. # Clean files
  118. minval = min([min(df['start']), min(df['target'])])
  119. i = 0
  120. while i < minval - 1:
  121. strlen = 1
  122. line = filenames[i]
  123. while string_in_arrays(line[:strlen], filenames):
  124. strlen = strlen + 1
  125. if strlen > len(line):
  126. break
  127. i = i + 1
  128. filenames = remove_substring(filenames[i][:strlen - 1], filenames)
  129.  
  130. # Transfer strings to lists
  131. arr = 0
  132. while arr < len(filenames):
  133. if not filenames[arr] == []:
  134. filenames[arr] = filenames[arr].strip('/')
  135. filenames[arr] = filenames[arr].split('/')
  136. # Cuts off unrequested detail
  137. if len(filenames[arr]) > depth:
  138. filenames[arr] = filenames[arr][:depth]
  139. arr = arr + 1
  140.  
  141. # Adds file lists to dictionary
  142. index = 0
  143. names = {}
  144. number = 0
  145. numbers = {}
  146. while index < len(filenames):
  147. names[index + 1] = filenames[index]
  148. index = index + 1
  149.  
  150. # Creates new columns for the arrays
  151. for col in cols:
  152. df[col + '_location'] = df[col].map(names)
  153. df[col + '_location'] = df[col + '_location'].apply(str)
  154. return df
  155.  
  156.  
  157. def string_in_arrays(string, array):
  158. """
  159. Input:
  160. string = string to be found
  161. arrays = array of arrays which contain strings
  162. Output: Bool, string in all the arrays
  163. """
  164. for str in array:
  165. if not string in str:
  166. return False
  167. return True
  168.  
  169.  
  170. def radialNodeLinkVis(G):
  171. pos = graphviz_layout(G, prog='twopi', args='')
  172. plt.figure(figsize=(8, 8))
  173. nx.draw(G, pos, node_size=20, alpha=0.5, node_color="blue", with_labels=False)
  174. plt.axis('equal')
  175. return (plt.show())
  176.  
  177.  
  178. def print_graph(sdf, time, start, target, hierarchy, width, depth, weight='weight',
  179. min_time='min', max_time='max', min_weight='min', max_weight='max'):
  180. """
  181. Prints a dynamic graph visualisation by drawing the static graphs of each
  182. timeslot ontop of each other. Incorperates a range of filering and
  183. aggregation tools.
  184.  
  185. Input
  186. ----------
  187. sdf = DataFrame with dynamic graph data
  188. time = time column of sdf DataFrame
  189. start = vertex column of sdf DataFrame where edges start
  190. target = vertex column of sdf DataFrame where edges end
  191. hierarchy = file where the hierarchy is stored, linked to values of vertices
  192. width = width in time steps of the time
  193. depth = maximum depth of hierarchy values
  194. weight = weight column of sdf DataFrame, default = 'weight'
  195. min_time = minimum value of time, default = minimum of sdf[time]
  196. max_time = maximum value of time, default = maximum of sdf[time]
  197. min_weight = minimum value of weight, default = minimum of sdf[weight]
  198. max_weight = maximum value of weight, default = maximum of sdf[weight]
  199.  
  200.  
  201. Output
  202. ----------
  203. Returns a Figure object
  204.  
  205. """
  206.  
  207. # Filter Dataset
  208. sdf = sdf.copy()
  209. if min_time == 'min':
  210. min_list = sdf[time] >= sdf[time].min()
  211. else:
  212. min_list = sdf[time] >= min_time
  213. if max_time == 'max':
  214. max_list = sdf[time] <= sdf[time].max()
  215. else:
  216. max_list = sdf[time] <= max_time
  217. sdf = sdf[min_list & max_list]
  218.  
  219. # recycle the list names
  220. if min_weight == 'min':
  221. min_list = sdf[weight] >= sdf[weight].min()
  222. else:
  223. min_list = sdf[weight] >= min_weight
  224. if max_weight == 'max':
  225. max_list = sdf[weight] <= sdf[weight].max()
  226. else:
  227. max_list = sdf[time] <= max_weight
  228. sdf = sdf[min_list & max_list]
  229.  
  230. # Transform Weights
  231. sdf['weight'] = sdf['weight'].apply(np.log10)
  232. sdf = sdf[min_list & max_list]
  233.  
  234. # Aggregates dataset
  235. sdf = range_aggregate(sdf, time, width)
  236. sdf = hierarchy_aggregate(sdf, [start, target], depth, hierarchy)
  237.  
  238. # Set aggregated names
  239. time_agg = time + '_grouped'
  240. start_agg = start + '_location'
  241. target_agg = target + '_location'
  242. headers = sdf.dtypes.index
  243.  
  244. # Checks if aggregate columns exist
  245. if time_agg in headers:
  246. time = time_agg
  247. if start_agg in headers and target_agg in headers:
  248. start = start_agg
  249. target = target_agg
  250. print(len(sdf))
  251. sdf['freq'] = sdf.groupby([time, start, target])['weight'].transform('count')
  252.  
  253. print(len(sdf))
  254. # Setup variables for creating the graph
  255. times = sdf[time].unique()
  256. end = {}
  257. fig = Figure(figsize=(12, 8), dpi=100)
  258. a = fig.add_subplot(111)
  259. a.get_xaxis().set_visible(False)
  260. a.get_yaxis().set_visible(False)
  261. offset = 5
  262. i = 0
  263.  
  264. # Creates dict for the end location of lines
  265. while i < len(times):
  266. try:
  267. end[times[i]] = times[i + offset]
  268. except:
  269. end[times[i]] = 'end+' + str(i + offset - len(times))
  270. i = i + 1
  271.  
  272. norm = Normalize(vmin=sdf['weight'].min(), vmax=sdf['weight'].max())
  273. cmap = cm.get_cmap(name='RdYlGn')
  274. m = cm.ScalarMappable(norm=norm, cmap=cmap)
  275.  
  276. # Plots every row in the dataframe to the plot
  277. for index, row in sdf.iterrows():
  278. x = [row[time], end[row[time]]]
  279. y = [row[start], row[target]]
  280. a.plot(x, y, alpha=0.3, c=m.to_rgba(row['weight']))
  281.  
  282. return fig
  283.  
  284.  
  285. class SampleApp(tk.Tk):
  286.  
  287. def __init__(self, *args, **kwargs):
  288. tk.Tk.__init__(self, *args, **kwargs)
  289.  
  290. self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
  291.  
  292. # the container is where we'll stack a bunch of frames
  293. # on top of each other, then the one we want visible
  294. # will be raised above the others
  295. container = tk.Frame(self)
  296. container.pack(side="top", fill="both", expand=True)
  297. container.grid_rowconfigure(0, weight=1)
  298. container.grid_columnconfigure(0, weight=1)
  299.  
  300. self.frames = {}
  301. for F in (StartPage, PageOne, PageTwo):
  302. page_name = F.__name__
  303. frame = F(parent=container, controller=self)
  304. self.frames[page_name] = frame
  305.  
  306. # put all of the pages in the same location;
  307. # the one on the top of the stacking order
  308. # will be the one that is visible.
  309. frame.grid(row=0, column=0, sticky="nsew")
  310.  
  311. self.show_frame("StartPage")
  312.  
  313. def show_frame(self, page_name):
  314. '''Show a frame for the given page name'''
  315. frame = self.frames[page_name]
  316. frame.tkraise()
  317.  
  318. def sel_df(self):
  319. # Select the txt file of the dataset
  320. self.path_df = filedialog.askopenfilename(initialdir="/", title
  321. ="Select file", filetypes
  322. =(("txt files", "*.txt"),
  323. ("all files", "*.*")))
  324. # Create df out of it and store it
  325. self.df = pd.read_table(self.path_df, delim_whitespace=True)
  326.  
  327. def sel_df_hier(self):
  328. # Select the txt file of the hierarchy dataset.
  329. self.path_df_hier = filedialog.askopenfilename(initialdir="/", title
  330. ="Select file", filetypes
  331. =(("txt files", "*.txt"),
  332. ("all files", "*.*")))
  333. # Create df out of it and store it
  334. self.df_hier = pd.read_table(self.path_df_hier, delim_whitespace=True)
  335.  
  336.  
  337. class StartPage(tk.Frame):
  338.  
  339. def __init__(self, parent, controller):
  340. tk.Frame.__init__(self, parent)
  341. self.controller = controller
  342. label = tk.Label(self, text="GUI group X", font=controller.title_font)
  343. label.pack(side="top", fill="x", pady=10)
  344.  
  345. button1 = tk.Button(self, text="Import main file",
  346. command=lambda: controller.sel_df())
  347. button2 = tk.Button(self, text="Import hierarchy file",
  348. command=lambda: controller.sel_df_hier())
  349. button3 = tk.Button(self, text="Adjacency matrix and Dynamic Graph",
  350. command=lambda: controller.show_frame("PageOne"))
  351. button4 = tk.Button(self, text="Exercise 7",
  352. command=lambda: controller.show_frame("PageTwo"))
  353.  
  354. button1.pack()
  355. button2.pack()
  356. button3.pack()
  357. button4.pack()
  358.  
  359.  
  360. class PageOne(tk.Frame):
  361.  
  362. def __init__(self, parent, controller):
  363. tk.Frame.__init__(self, parent)
  364. self.controller = controller
  365. label = tk.Label(self, text="Adjacency Matrix and Dynamic Graph", font=controller.title_font)
  366. label.pack(side="top", fill="x", pady=10)
  367. button = tk.Button(self, text="Go to the start page",
  368. command=lambda: controller.show_frame("StartPage"))
  369. button.pack()
  370.  
  371. f = print_graph(df, 'time', 'start', 'target', hierarchyfile, 1, 5, weight='weight',
  372. min_time=1, max_time=300, min_weight=0, max_weight='max')
  373.  
  374.  
  375. # Create canvas
  376. canvas = FigureCanvasTkAgg(f, self)
  377. canvas.draw
  378. canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
  379.  
  380. # Add standard-layout
  381. toolbar = NavigationToolbar2Tk(canvas, self)
  382. toolbar.update()
  383. canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
  384.  
  385. # Create entries which will be used by the graph:
  386. label_e1 = Label(self, text="Range")
  387. label_e2 = Label(self, text="Hierarchy")
  388.  
  389. e = Entry(self)
  390. e.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
  391.  
  392.  
  393. class PageTwo(tk.Frame):
  394.  
  395. def __init__(self, parent, controller):
  396. tk.Frame.__init__(self, parent)
  397. self.controller = controller
  398. label = tk.Label(self, text="Exercise 7", font=controller.title_font)
  399. label.pack(side="top", fill="x", pady=10)
  400. button = tk.Button(self, text="Go to the start page",
  401. command=lambda: controller.show_frame("StartPage"))
  402. button.pack()
  403.  
  404.  
  405. if __name__ == "__main__":
  406. app = SampleApp()
  407. app.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement