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:

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 + xdist – xgap
y2 = y + ydist – ygap
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();
}
}
