Custom Outputs

Overview

Artemis allows you to create custom output anchors to display or visualize variables in custom ways. For example, if you want to use the output anchor to display a variable in the form of a specialized graph not offered by Artemis, you can create your own custom output anchor to accomplish this.

Usage

  1. Open command prompt and type artemis_labs config. This will open the Artemis configuration Python file in your native IDE. There should already be multiple examples of output anchors here, ranging from line_graph to scatter_graph
  2. To create a new anchor, you will need to go to the bottom of this file and create a new function. This new function must have the first input be the variable you're outputting and the second input be the list of named_args associated with this anchor. You are not required to use both arguments, but you must match this function definition structure.
  3. Inside the function, you may find the following functions useful:
FunctionPurpose
ArtemisHelper.assert_input_is_type(type)Asserts a variable is a certain type
ArtemisHelper.assert_true(condition)Asserts a condition
ArtemisHelper.convert_if(variable, ArtemisType.FROM_TYPE, ArtemisType.TO_TYPE)Converts a variable betwen types only if the variable is ArtemisType.FROM_TYPE in the first place
  1. Once you finish creating your output, you have to serialize your output and return this result. This transforms your output into a form that that can be displayed in the Artemis development environment. The command to do this is ArtemisHelper.serialize(VARIABLE, ArtemisType.VARIABLE_TYPE). The following types may be serialized:
Variable TypeArtemis TypeExample
Matplotlib PlotArtemisType.MATPLOTLIB_PLOTArtemisHelper.serialize(None, ArtemisType.MATPLOTLIB_PLOT)
Matplotlib FigureArtemisType.MATPLOTLIB_FIGUREArtemisHelper.serialize(fig, ArtemisType.MATPLOTLIB_FIGURE)
  1. Finally, underneath the function, you must register your function. This binds your function to the anchor name. You must do this by calling ArtemisConfigManager.register_function(function_name, 'anchor name').

Named Arguments

None

Examples

'''
Description: Function to create an output from a Matplotlib figure
@param fig - Matplotlib Figure
@returns Serialized Matplotlib figure
'''
def graph(fig, named_args : Dict) -> Tuple:

    # Validate input is a Matplotlib Figure
    ArtemisHelper.assert_input_is_type(fig, plt.Figure)

    # Serialize fig, indicating it is type ArtemisType.MATPLOTLIB_FIGURE
    return ArtemisHelper.serialize(fig, ArtemisType.MATPLOTLIB_FIGURE)
  
'''
Register graph as the function bound to the output decorator graph:
This means we call graph when we do @output graph

Example Usage:
fig = plt.figure()
plt.plot(data)
@output graph data=fig
'''
ArtemisConfigManager.register_function(graph, 'graph')
'''
Description: Function to create a line graph output from an input nx2 array
@param arr - nx2 numpy array of data points to plot
@returns Serialized Matplotlib plot
'''
def line_graph(arr, named_args : Dict) -> Tuple:

    # Convert input array to numpy array if it is a list
  arr = ArtemisHelper.convert_if(arr, ArtemisType.LIST, ArtemisType.NUMPY_ARRAY)

  # Validate input is a numpy array
  ArtemisHelper.assert_input_is_type(arr, np.ndarray)

  # Update the plot title if we have this named arg
  if 'title' in named_args:
    plt.title(named_args['title'])

  # Plot data
  plt.plot(arr[:,0], arr[:,1])
    
  # Serialize Matplotlib plot and return serialized output 
  return ArtemisHelper.serialize(None, ArtemisType.MATPLOTLIB_PLOT)
  
'''
Register line_graph as the function bound to the output decorator line-graph:
This means we call line_graph when we do @output line-graph

Example Usage:
@output line-graph
np.array([[1,1],[2,2],[3,3],[4,4],[5,5]])
'''
ArtemisConfigManager.register_function(line_graph, 'line-graph')
'''
Description: Function to create a line graph output from a list containing the x's and y's to plot
@param list_arr - list containing an array of x's and an array of y's
@returns Serialized Matplotlib figure
'''
def line_graph_x_y(list_arr, named_args : Dict) -> Tuple:

  # Validate input is a list
  ArtemisHelper.assert_input_is_type(list_arr, list)

  # Pick out x and y values
  ArtemisHelper.assert_true(len(list_arr) == 2)

  # Get x's and y's
  x = list_arr[0]
  y = list_arr[1]

  # Convert x and y to numpy arrays if lists
  x = ArtemisHelper.convert_if(x, ArtemisType.LIST, ArtemisType.NUMPY_ARRAY)
  y = ArtemisHelper.convert_if(y, ArtemisType.LIST, ArtemisType.NUMPY_ARRAY)

  # Update the plot title if we have this named arg
  if 'title' in named_args:
        plt.title(named_args['title'])
    
  # Plot data, using x as the x's and y as the y's
  plt.plot(x,y)
    
  # Serialize Matplotlib plot and return serialized output 
  return ArtemisHelper.serialize(None, ArtemisType.MATPLOTLIB_PLOT)
  
'''
Register line_graph_x_y as the function bound to the output decorator line-graph-x-y:

This means we call graph when we do @output line-graph-x-y
Example Usage:
x_data = np.array([1,2,3,4,5])
y_data = np.random.normal(0, 1, 5)
@output line_graph_x_y
[x_data, y_data]
'''
ArtemisConfigManager.register_function(line_graph_x_y, 'line-graph-x-y')

Did this page help you?