"""
Backend Utility functions for Visualising
@Author Max Hall
@Co-Authors Meghan Ireland and Matthew Fleischman
"""
# Imports
import os
import utils.helper_methods as hm
[docs]
class WriteVisualFiles:
''' This is a base class which will allow us to complete the task of writing to the
models visualisation files '''
def __init__(self, model, visualiser):
"""Writes the visualisation into its section.
Parameters
----------
model : ModelEnv
This allows the functions to access the necessary info to write to the file
visualiser : VisualEnv
This allows the functions to access the necessary info to write to the file
"""
# Holds the user provided model as well as the storing string for each new visualisation
# file body
self.model = model
self.visualiser = visualiser
self.visualisation_section = "" # Code for data visualisation file
[docs]
def create_visualisation_file_section(self, visual_plot_id : str):
"""Writes the visualisation into its section.
Parameters
----------
visual_plot_id : str
Specifies the visual plot id to be plotted
Returns
-------
error term : int
Returns 0 on success
Returns 1 if creation fails, prints error message in terminal
"""
try:
# Initialisises the section
self.visualisation_section = ""
# Create basic class details
self.visualisation_section += "#"*10 + "Imports" + "#"*10 + "\n"
self.visualisation_section += "import matplotlib.pyplot as plt\n"
self.visualisation_section += "from jsonpickle import dumps, decode\n\n\n"
self.visualisation_section += "#"*10 + "Visualisation" + "#"*10 + "\n"
# Initialisation Method
self.visualisation_section += "def visualise("
self.visualisation_section += "json_file_name : str = 'dataFiles/records.json'):\n"
self.visualisation_section += "\t''' Data Visualisation '''\n"
# Load in data
self.visualisation_section += "\twith open(json_file_name, 'r') as file:\n"
self.visualisation_section += "\t\trecords = decode(file.read())\n\n"
# Load in record dictionaries for each agent
visual_agent = self.visualiser.get_agent_visualisation(visual_plot_id)
agent_name = visual_agent.get_visual_agent_name()
compare_agent_list = visual_agent.get_compare_agent_list()
self.visualisation_section += f"\t{agent_name}_records = "
self.visualisation_section += f"records['{agent_name}_records']\n"
# Load in comparing agents
for compare_agent in compare_agent_list:
self.visualisation_section += f"\t{compare_agent}_records"
self.visualisation_section += f" = records['{compare_agent}_records']\n"
# Get the base data to Visualise given visualisation
visual_agent = self.visualiser.get_agent_visualisation(visual_plot_id)
agent_name = visual_agent.get_visual_agent_name()
# Load visual details into variables
compare_agent_list = visual_agent.get_compare_agent_list()
comp_of_interest = visual_agent.get_comp_of_interest()
attr_of_interest = visual_agent.get_attr_of_interest()
plot_data_type = visual_agent.get_plot_data_type()
plot_type = visual_agent.get_plot_type()
# Comment agent type being visualised
self.visualisation_section += f"# {agent_name} Agent Visualisation\n"
# Plot for the keep count interest
if plot_data_type == "count":
plot_title = "Number of Agents Over Time"
plotting_string = hm.plotting_string("\t", agent_name, "", "count", plot_type
, plot_title, "Iteration", "Count"
, compare_agent_list)
self.visualisation_section += plotting_string
# Plot for the individual interest
elif plot_data_type == "individual":
# call plotting string
plot_title = f"Final {attr_of_interest.capitalize()} Values for Each Agent ID"
plotting_string = hm.plotting_string("\t", agent_name
, f"{comp_of_interest}_{attr_of_interest}"
, "individual", plot_type, plot_title
, "Agent"
, (attr_of_interest.capitalize() + " value")
, compare_agent_list)
self.visualisation_section += plotting_string
# Plot for rest of types
else:
# call plotting string
title = plot_data_type.capitalize().replace("_val", " Value")
plot_title = f"{title} of {attr_of_interest} Over Time"
plotting_string = hm.plotting_string("\t", agent_name
, f"{comp_of_interest}_{attr_of_interest}"
, plot_data_type, plot_type, plot_title
, "Iteration", title, compare_agent_list)
self.visualisation_section += plotting_string
self.visualisation_section += "if __name__ == '__main__':"
self.visualisation_section += "\n\tvisualise('dataFiles/records.json')"
return 0
except Exception as exception:
print(exception)
return 1
[docs]
def create_visualisation_file(self, plot_name : str):
"""Writes the main/runtime into the file.
Parameters
----------
plot_name : str
The name of the plot which is being written and thus its filename
Returns
-------
error term : int
Returns 0 on success
Returns 1 if write fails, prints error message in terminal
"""
try:
formatted_plot_name = hm.getting_name_checker(plot_name
, self.visualiser.get_list_visuals())
if formatted_plot_name in [1,2]:
raise Exception("Plot name for VisualiseAgent provided has not yet been created!")
if not os.path.isdir("visualisingFiles"):
os.makedirs("visualisingFiles")
with open(f"visualisingFiles/{formatted_plot_name}_visual.py", 'w', encoding='UTF-8') as file:
self.create_visualisation_file_section(formatted_plot_name)
file.write(self.visualisation_section)
print(f"Done Creating visualisingFiles/{formatted_plot_name}_visual.py")
return 0
except Exception as exception:
if str(exception) == "Plot name for VisualiseAgent provided has not yet been created!":
print(exception)
else: # pragma: no cover
print(f"Failed Creating visualisingFiles/{formatted_plot_name}_visual.py")
return 1