Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- """
- Created on Mon Dec 10 20:35:34 2018
- @author: Jaymon
- """
- import tkinter as tk # python 3
- from tkinter import font as tkfont # python 3]
- from tkinter import filedialog
- from matplotlib.widgets import Slider
- from tkinter import *
- import pandas as pd
- import numpy as np
- try:
- import pygraphviz
- from networkx.drawing.nx_agraph import graphviz_layout
- except ImportError:
- try:
- import pydot
- from networkx.drawing.nx_pydot import graphviz_layout
- except ImportError:
- raise ImportError("This script needs Graphviz and either "
- "PyGraphviz or pydot")
- import matplotlib
- import matplotlib.cm as cm
- from matplotlib.colors import Normalize
- import networkx as nx
- # Import backend of matplotlib
- matplotlib.use("TkAgg")
- from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
- from matplotlib.figure import Figure
- hierarchyfile = 'profile_semantic_trafo_final_hierarchy.txt'
- datafile = 'profile_semantic_trafo_final.txt'
- df = pd.read_table(datafile, delim_whitespace=True)
- def remove_substring(string, array):
- """
- Input:
- string = string to be removed
- arrays = array of arrays which contain strings
- Output: cleaned array
- """
- i = 0
- while i < len(array):
- array[i] = array[i].replace(string, '')
- i = i + 1
- return array
- def range_aggregate(sdf, col, size):
- """
- Aggregated the values in col to bins of the width of size.
- Input
- ----------
- df = Dataframe time value in col
- col = Column with time value
- size = the width of the filter
- Output
- ----------
- Dataframe object
- """
- df = sdf
- times = df[col].unique()
- if size < len(times) / 2 and size > 1:
- aggregated = {}
- i = 0
- time = 0
- while time < len(times):
- if i == 0:
- try:
- name = str(times[time]) + '-' + str(times[size + time - 1])
- except:
- name = str(times[time]) + '-' + str(times[-1])
- aggregated[str(times[time])] = name
- i = i + 1
- time = time + 1
- if i == size:
- i = 0
- df[col + '_grouped'] = df[col].apply(str)
- df[col + '_grouped'] = df[col + '_grouped'].map(aggregated)
- return df
- def hierarchy_aggregate(sdf, cols, depth, hierarchy_file):
- """
- Turns all of the columns in cols into hierarchy strings trimed to a
- maximum depth.
- Input
- ----------
- df = Dataframe
- cols = Array with column values
- depth = depth of hierarchy
- Output
- ----------
- DataFrame with an aditional col for each col in cols
- """
- df = sdf
- # Import hierarchy names
- hierarchy = open(hierarchy_file)
- filenames = []
- for line in hierarchy:
- line = line.rstrip()
- filenames.append(line)
- hierarchy.close()
- # Clean files
- minval = min([min(df['start']), min(df['target'])])
- i = 0
- while i < minval - 1:
- strlen = 1
- line = filenames[i]
- while string_in_arrays(line[:strlen], filenames):
- strlen = strlen + 1
- if strlen > len(line):
- break
- i = i + 1
- filenames = remove_substring(filenames[i][:strlen - 1], filenames)
- # Transfer strings to lists
- arr = 0
- while arr < len(filenames):
- if not filenames[arr] == []:
- filenames[arr] = filenames[arr].strip('/')
- filenames[arr] = filenames[arr].split('/')
- # Cuts off unrequested detail
- if len(filenames[arr]) > depth:
- filenames[arr] = filenames[arr][:depth]
- arr = arr + 1
- # Adds file lists to dictionary
- index = 0
- names = {}
- number = 0
- numbers = {}
- while index < len(filenames):
- names[index + 1] = filenames[index]
- index = index + 1
- # Creates new columns for the arrays
- for col in cols:
- df[col + '_location'] = df[col].map(names)
- df[col + '_location'] = df[col + '_location'].apply(str)
- return df
- def string_in_arrays(string, array):
- """
- Input:
- string = string to be found
- arrays = array of arrays which contain strings
- Output: Bool, string in all the arrays
- """
- for str in array:
- if not string in str:
- return False
- return True
- def radialNodeLinkVis(G):
- pos = graphviz_layout(G, prog='twopi', args='')
- plt.figure(figsize=(8, 8))
- nx.draw(G, pos, node_size=20, alpha=0.5, node_color="blue", with_labels=False)
- plt.axis('equal')
- return (plt.show())
- def print_graph(sdf, time, start, target, hierarchy, width, depth, weight='weight',
- min_time='min', max_time='max', min_weight='min', max_weight='max'):
- """
- Prints a dynamic graph visualisation by drawing the static graphs of each
- timeslot ontop of each other. Incorperates a range of filering and
- aggregation tools.
- Input
- ----------
- sdf = DataFrame with dynamic graph data
- time = time column of sdf DataFrame
- start = vertex column of sdf DataFrame where edges start
- target = vertex column of sdf DataFrame where edges end
- hierarchy = file where the hierarchy is stored, linked to values of vertices
- width = width in time steps of the time
- depth = maximum depth of hierarchy values
- weight = weight column of sdf DataFrame, default = 'weight'
- min_time = minimum value of time, default = minimum of sdf[time]
- max_time = maximum value of time, default = maximum of sdf[time]
- min_weight = minimum value of weight, default = minimum of sdf[weight]
- max_weight = maximum value of weight, default = maximum of sdf[weight]
- Output
- ----------
- Returns a Figure object
- """
- # Filter Dataset
- sdf = sdf.copy()
- if min_time == 'min':
- min_list = sdf[time] >= sdf[time].min()
- else:
- min_list = sdf[time] >= min_time
- if max_time == 'max':
- max_list = sdf[time] <= sdf[time].max()
- else:
- max_list = sdf[time] <= max_time
- sdf = sdf[min_list & max_list]
- # recycle the list names
- if min_weight == 'min':
- min_list = sdf[weight] >= sdf[weight].min()
- else:
- min_list = sdf[weight] >= min_weight
- if max_weight == 'max':
- max_list = sdf[weight] <= sdf[weight].max()
- else:
- max_list = sdf[time] <= max_weight
- sdf = sdf[min_list & max_list]
- # Transform Weights
- sdf['weight'] = sdf['weight'].apply(np.log10)
- sdf = sdf[min_list & max_list]
- # Aggregates dataset
- sdf = range_aggregate(sdf, time, width)
- sdf = hierarchy_aggregate(sdf, [start, target], depth, hierarchy)
- # Set aggregated names
- time_agg = time + '_grouped'
- start_agg = start + '_location'
- target_agg = target + '_location'
- headers = sdf.dtypes.index
- # Checks if aggregate columns exist
- if time_agg in headers:
- time = time_agg
- if start_agg in headers and target_agg in headers:
- start = start_agg
- target = target_agg
- print(len(sdf))
- sdf['freq'] = sdf.groupby([time, start, target])['weight'].transform('count')
- print(len(sdf))
- # Setup variables for creating the graph
- times = sdf[time].unique()
- end = {}
- fig = Figure(figsize=(12, 8), dpi=100)
- a = fig.add_subplot(111)
- a.get_xaxis().set_visible(False)
- a.get_yaxis().set_visible(False)
- offset = 5
- i = 0
- # Creates dict for the end location of lines
- while i < len(times):
- try:
- end[times[i]] = times[i + offset]
- except:
- end[times[i]] = 'end+' + str(i + offset - len(times))
- i = i + 1
- norm = Normalize(vmin=sdf['weight'].min(), vmax=sdf['weight'].max())
- cmap = cm.get_cmap(name='RdYlGn')
- m = cm.ScalarMappable(norm=norm, cmap=cmap)
- # Plots every row in the dataframe to the plot
- for index, row in sdf.iterrows():
- x = [row[time], end[row[time]]]
- y = [row[start], row[target]]
- a.plot(x, y, alpha=0.3, c=m.to_rgba(row['weight']))
- return fig
- class SampleApp(tk.Tk):
- def __init__(self, *args, **kwargs):
- tk.Tk.__init__(self, *args, **kwargs)
- self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
- # the container is where we'll stack a bunch of frames
- # on top of each other, then the one we want visible
- # will be raised above the others
- container = tk.Frame(self)
- container.pack(side="top", fill="both", expand=True)
- container.grid_rowconfigure(0, weight=1)
- container.grid_columnconfigure(0, weight=1)
- self.frames = {}
- for F in (StartPage, PageOne, PageTwo):
- page_name = F.__name__
- frame = F(parent=container, controller=self)
- self.frames[page_name] = frame
- # put all of the pages in the same location;
- # the one on the top of the stacking order
- # will be the one that is visible.
- frame.grid(row=0, column=0, sticky="nsew")
- self.show_frame("StartPage")
- def show_frame(self, page_name):
- '''Show a frame for the given page name'''
- frame = self.frames[page_name]
- frame.tkraise()
- def sel_df(self):
- # Select the txt file of the dataset
- self.path_df = filedialog.askopenfilename(initialdir="/", title
- ="Select file", filetypes
- =(("txt files", "*.txt"),
- ("all files", "*.*")))
- # Create df out of it and store it
- self.df = pd.read_table(self.path_df, delim_whitespace=True)
- def sel_df_hier(self):
- # Select the txt file of the hierarchy dataset.
- self.path_df_hier = filedialog.askopenfilename(initialdir="/", title
- ="Select file", filetypes
- =(("txt files", "*.txt"),
- ("all files", "*.*")))
- # Create df out of it and store it
- self.df_hier = pd.read_table(self.path_df_hier, delim_whitespace=True)
- class StartPage(tk.Frame):
- def __init__(self, parent, controller):
- tk.Frame.__init__(self, parent)
- self.controller = controller
- label = tk.Label(self, text="GUI group X", font=controller.title_font)
- label.pack(side="top", fill="x", pady=10)
- button1 = tk.Button(self, text="Import main file",
- command=lambda: controller.sel_df())
- button2 = tk.Button(self, text="Import hierarchy file",
- command=lambda: controller.sel_df_hier())
- button3 = tk.Button(self, text="Adjacency matrix and Dynamic Graph",
- command=lambda: controller.show_frame("PageOne"))
- button4 = tk.Button(self, text="Exercise 7",
- command=lambda: controller.show_frame("PageTwo"))
- button1.pack()
- button2.pack()
- button3.pack()
- button4.pack()
- class PageOne(tk.Frame):
- def __init__(self, parent, controller):
- tk.Frame.__init__(self, parent)
- self.controller = controller
- label = tk.Label(self, text="Adjacency Matrix and Dynamic Graph", font=controller.title_font)
- label.pack(side="top", fill="x", pady=10)
- button = tk.Button(self, text="Go to the start page",
- command=lambda: controller.show_frame("StartPage"))
- button.pack()
- f = print_graph(df, 'time', 'start', 'target', hierarchyfile, 1, 5, weight='weight',
- min_time=1, max_time=300, min_weight=0, max_weight='max')
- # Create canvas
- canvas = FigureCanvasTkAgg(f, self)
- canvas.draw
- canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
- # Add standard-layout
- toolbar = NavigationToolbar2Tk(canvas, self)
- toolbar.update()
- canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
- # Create entries which will be used by the graph:
- label_e1 = Label(self, text="Range")
- label_e2 = Label(self, text="Hierarchy")
- e = Entry(self)
- e.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
- class PageTwo(tk.Frame):
- def __init__(self, parent, controller):
- tk.Frame.__init__(self, parent)
- self.controller = controller
- label = tk.Label(self, text="Exercise 7", font=controller.title_font)
- label.pack(side="top", fill="x", pady=10)
- button = tk.Button(self, text="Go to the start page",
- command=lambda: controller.show_frame("StartPage"))
- button.pack()
- if __name__ == "__main__":
- app = SampleApp()
- app.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement