Name and Classification: Activation Diagram (Classification: Dynamics, Micro-Mechanics, Macro Behaviours)

Intent: Visualize micro-level activation of components over time to see macro-level characteristics.

Also known as: Gene expression diagram, gene activation diagram, expression pattern, activation signature

Motivation: Understanding the effects over time of interactions between large numbers of nodes in a network can be difficult and time-consuming. Inferring macro-level classes of behaviour is easiest when the history of system-wide activations are presented as a single diagram. The idea of this pattern is to provide a visualization of node histories for a single initial condition, allowing macro-level features such as stable, cyclic, or chaotic behaviour to be identified, and characteristics such as the length of transient periods to be measured.

Applicability: Use the Activation Diagram pattern when you want to

  • visualize the characteristics of component activations over time when components have binary or real-valued states
  • visualize characteristics of macro level behaviour such as ordered, cyclic, or chaotic activity
  • visualize both the initial transient dynamics and the longer term behaviour
  • assess the lifecycle of macro level behaviours (such as the number of steps before a network settles into a certain state)
  • (variation) manually investigate robustness of macro-level behaviour

Structure:

Participants:

Collaborations:

Example Visualization:

Activation Diagram

 

 

Figure 1. Activation Diagram. Time is shown along the x axis, and each component is positioned along the y axis. Active components are denoted by blue shading. This diagram shows the component interactions falling into a cyclic state after a short transient period.

 

 

Consequences: The Activation Diagram has the following consequences and inherent limitations:

  • it provides a clean visualization of the dynamics from a single starting state but the inherent limitation is that only a single starting state and trajectory is shown per diagram
  • it requires access to the values of all components for each time step
  • large numbers of components can make viewing difficult
  • very long cycles can appear similar to chaotic trajectories
  • the two-dimensional representation maps time into space, consequently spatial information is lost (e.g., in random Boolean networks, neural networks); this can be mitigated by using the Activation Diagram pattern together with the Network Diagram pattern
  • spatial information is preserved if a one-dimensional representation is used (e.g., cellular automata)

Implementation: The Activation Diagram has the following important implementation variations:

  • time can be expressed along the x or y axis
  • one-dimensional interactions (e.g., cellular automata) can be visualized by ordering nodes according to their interactions

Known Uses: Gene expression (Reil), cellular automata (Von Neumann? ~ 1950’s), random Boolean networks (Wuensche?), neural network dynamics

Related Patterns: State-Space Diagram, Network Diagram, Matlab NN Toolbox?

Sample Code:
This example visualizes the expression pattern of a Boolean network of gene regulation.

e = expression data, indexed by [step number][gene number]
s = number of steps in e
g = number of genes in e

if (s > 0) and (g > 0):
	      clear the screen
	      xdist = screen-width / s
	      ydist = screen-height / g
	      xgap = 0.12 * xdist
	      ygap = 0.12 *  ydist

	      x = 0  /* where 0 is leftmost screen coordinate */
	      for i = 1 to s:
	            y = 0  /* where 0 is topmost screen coordinate */
	            for j = 1 to g:
	                  if expression_data[i][j] is activated:
	                        x1 = x + xgap
	                        y1 = y + ygap
	                        x2 = x + xdistxgap
	                        y2 = y + ydistygap
	                        draw_rectangle(x1, y1, x2, y2)
	                  y = y + ydist
	            x = x + xdist

What follows is an implementation of the Activation Diagram pattern using C++, OpenGL and wxWidgets.  This example also visualizes the expression pattern of a Boolean network of gene regulation.

Initialization of Window and drawing canvas, and declaration of window event table and destructor.

EBrowser::EBrowser(GenomeDisplay *parent)
	            : wxFrame(parent, -1, "", wxDefaultPosition, wxSize(650,430))
	{
	      gDisplay = parent;
	      num = gDisplay->num;
	      num_steps = -1;

	      wxString title = "Gene Expression of Genome " +
	                  wxString::Format("%d", num);
	      SetTitle(title);

	      canvas = new ECanvas(this);
	}

	void EBrowser::OnClose(wxCommandEvent & event)
	{
	      Show(false);
	}
	EBrowser::~EBrowser()
	{
	      delete canvas;
	}
	
	BEGIN_EVENT_TABLE(EBrowser, wxFrame)
	      EVT_CLOSE(EBrowser::OnClose)
	END_EVENT_TABLE()

	

Specification of the number of steps in the visualization and start the visualization.

void EBrowser::SetNumSteps(int numSteps)
	{
	      num_steps = numSteps;
	      wxString title = "Gene Expression of Genome " +
	                  wxString::Format("%d", num) + ": " +
	                  wxString::Format("%d", num_steps) + " Steps";
	      SetTitle(title);
	
	      update();
	}

	void EBrowser::update()
	{
	      if (num_steps > 0)
	            canvas->update(num_steps);
	}

Define the drawing canvas as a member of the main window.  This has access to the expression data.  Its initialization also initializes the graphics toolkit (OpenGL in this case).

ECanvas::ECanvas(EBrowser *parent)
	            : wxGLCanvas(parent, -1, wxDefaultPosition, wxDefaultSize)
	{
	      gDisplay = parent->gDisplay;

	      exp_data = new expression_data;
	      exp_data->steps = 0;
	      exp_data->num_genes = 0;
	      exp_data->data = NULL;
	
	      SetCurrent();
	      glMatrixMode(GL_PROJECTION);
	}

	ECanvas::~ECanvas()
	{
	      gDisplay->genome->freeExpData(exp_data);
	}

	BEGIN_EVENT_TABLE(ECanvas, wxGLCanvas)
	      EVT_SIZE(ECanvas::OnSize)
	      EVT_PAINT(ECanvas::OnPaint)
	      EVT_ERASE_BACKGROUND(ECanvas::OnEraseBackground)
	      EVT_LEFT_UP(ECanvas::OnMouseClick)
	END_EVENT_TABLE()


	void ECanvas::OnPaint(wxPaintEvent & event)
	{
	      wxPaintDC dc(this);
	      renderExpData();
	}

	void ECanvas::OnSize(wxSizeEvent & event)
	{
	      int width, height;
	      GetClientSize(&width, &height);
	      if (GetContext())
	      {
	            SetCurrent();
	            glViewport(0, 0, width, height);
	      }
	}

	void ECanvas::OnEraseBackground(wxEraseEvent & event)
	{
	      //to avoid flashing
	}

	

Allow the visualization to be re-initialized.

// (re)initialize expression data structure
	void ECanvas::update(int num_steps)
	{
	      gDisplay->genome->getExpressionData(exp_data, num_steps);
	      renderExpData();
	}

Function which graphically renders the expression data to screen.

void ECanvas::renderExpData()
	{
	      if ((exp_data->steps > 0) && (exp_data->num_genes > 0))
	      {
	            SetCurrent();
	            glClearColor(1.0, 1.0, 1.0, 1.0);
	            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	            // opengl coords: -1 -> 1
	            double x_dist = 2.0 / exp_data->steps;
	            double y_dist = 2.0 / exp_data->num_genes;
	            double x_gap = 0.25 * x_dist / 2;
	            double y_gap = 0.25 * y_dist / 2;

	            // display activated genes
	            SetColour(ebExpColour);
	            double x = -1;
	            for (unsigned int i = 0; i < exp_data->steps; i++)
	            {
	                  double y = -1;
	                  for (unsigned int j = 0; j < exp_data->num_genes; j++)
	                  {
	                        if (exp_data->data[i][j] == 1)
	                        {
	                              // display gene as activated
	                              double x1 = x + x_gap;
	                              double y1 = y + y_gap;
	                              double x2 = x + x_dist - x_gap;
	                              double y2 = y + y_dist - y_gap;
	                              glRectf(x1, y1, x2, y2);
	                        }
	                        y += y_dist;
	                  }
	                  x += x_dist;
	            }
	            SwapBuffers();
	      }
	}

	

(Variation) Allow the user to toggle a gene’s activation state at an arbitrary point in time, using the mouse.  This requires conversion of the window’s coordinate system to the corresponding expression pattern value, and the re-evaluation of the expression values from that time-step.

// method that allows the toggling of a gene's activation state
	void ECanvas::OnMouseClick(wxMouseEvent & event)
	{
	      if ((exp_data->steps > 0) && (exp_data->num_genes > 0))
	      {
	            /* coordinates returned by event are such that the top
	             * left-hand corner is (0,0), bottom-right is size */
	            int width, height;
	            GetClientSize(&width, &height);
	            double x_fraction = (double)(event.GetX()) /
	                  (double)width;
	            double y_fraction = (double)(event.GetY()) /
	                  (double)height;
	            // x,y relative to the 0->2 values of the axes
	            double x = x_fraction * 2;
	            double y = 2 - y_fraction * 2;

	            // determine which gene was clicked on
	            double x_dist = 2.0 / exp_data->steps;
	            double y_dist = 2.0 / exp_data->num_genes;
	            int step = (int)(x / x_dist);
	            int gene = (int)(y / y_dist);

	            // toggle this gene
	            if (exp_data->data[step][gene] == 0)
	                  exp_data->data[step][gene] = 1;
	            else
	                  exp_data->data[step][gene] = 0;
	            gDisplay->genome->updatedExpressionData(exp_data, step);

	            renderExpData();
	      }
	}