diff --git a/src/main.c b/src/main.c
index 88cd00a6c21089612484955ce9b974acd13df6b2..2a2068920daf4b375c0026c3d190799d29b3d350 100644
--- a/src/main.c
+++ b/src/main.c
@@ -5,6 +5,11 @@
 
 /* TYPES!!! */
 
+struct column_list {
+	struct column_list* next;
+	char* header;
+};
+
 struct data {
 
 	struct data* next;
@@ -14,6 +19,7 @@ struct data {
 	struct {
 		double v;
 		bool present;
+		enum { LEFT, RIGHT, } axis;
 	} y[];
 
 };
@@ -26,8 +32,15 @@ struct context {
 	struct data* data;
 	struct data* data_end;
 
-	char** headers;
-	size_t n_headers;
+	struct column_list* left_columns;
+	struct column_list* ignore_columns;
+
+	struct {
+		char* header;
+		enum { XAXIS, LEFT_AXIS, RIGHT_AXIS, IGNORE, } type;
+	} * columns;
+	size_t n_columns;
+	size_t n_data_columns;
 
 	struct timespec start_time;
 
@@ -44,8 +57,11 @@ struct context {
 	double xpos;
 	bool xfollow;
 
-	double ydist; /* 0 for fit all */
-	double ypos;
+	double yldist; /* 0 for fit all */
+	double ylpos;
+
+	double yrdist; /* 0 for fit all */
+	double yrpos;
 
 };
 
@@ -58,6 +74,8 @@ struct fd_source {
 
 /* PROTOTYPES!!! */
 
+static bool add_to_column_list( const char* option_name,
+	const char* value, void* data, GError** error );
 static int parse_hex( float res[3], const char* hex );
 static void app_activate( GtkApplication* app, void* data );
 static int listener_prepare( GSource* source, int* timeout );
@@ -105,20 +123,39 @@ int main( int argc, char** argv ) {
 		{
 			.long_name = "x-axis",
 			.short_name = 'x',
-			.flags = G_OPTION_FLAG_NONE,
+			.flags = G_OPTION_FLAG_IN_MAIN,
 			.arg = G_OPTION_ARG_STRING,
 			.arg_data = &( context->xaxis ),
 			.description = "Column to use as the x-axis",
 			.arg_description = "column",
+		}, {
+			.long_name = "right",
+			.short_name = 'r',
+			.flags = G_OPTION_FLAG_IN_MAIN,
+			.arg = G_OPTION_ARG_CALLBACK,
+			.arg_data = &add_to_column_list,
+			.description = "Use right axis for column",
+			.arg_description = "column"
+		}, {
+			.long_name = "ignore",
+			.short_name = 'i',
+			.flags = G_OPTION_FLAG_IN_MAIN,
+			.arg = G_OPTION_ARG_CALLBACK,
+			.arg_data = &add_to_column_list,
+			.description = "Do not plot the data in column",
+			.arg_description = "column"
 		}, {
 			NULL,
 		},
 	};
+	GOptionGroup* option_group = g_option_group_new( "", "", "",
+		context, NULL );
+	g_option_group_add_entries( option_group, options );
 
 	GtkApplication* app = gtk_application_new(
 		"uk.ac.soton.ecs.e-plot", G_APPLICATION_DEFAULT_FLAGS );
-	g_application_add_main_option_entries(
-		G_APPLICATION( app ), options );
+	g_application_add_option_group(
+		G_APPLICATION( app ), option_group );
 	g_signal_connect(
 		app, "activate", G_CALLBACK( app_activate ), context );
 
@@ -132,6 +169,31 @@ int main( int argc, char** argv ) {
 
 /* PRIVATE FUNK!!! */
 
+static bool add_to_column_list( const char* option_name,
+		const char* value, void* data, GError** error ) {
+
+	struct context* context = (struct context*) data;
+	(void) error;
+
+	struct column_list* item = calloc( 1, sizeof *item );
+	item->header = strdup( value );
+
+	if ( 0 == strcmp( option_name, "-r" ) ||
+			0 == strcmp( option_name, "--right" ) ) {
+		item->next = context->left_columns;
+		context->left_columns = item;
+	} else if ( 0 == strcmp( option_name, "-i" ) ||
+			0 == strcmp( option_name, "--ignore" ) ) {
+		item->next = context->ignore_columns;
+		context->ignore_columns = item;
+	} else {
+		assert( false );
+	}
+
+	return true;
+
+}
+
 static int parse_hex( float res[3], const char* hex ) {
 
 	while ( ' ' == *hex || '\t' == *hex || '#' == *hex ) {
@@ -375,7 +437,7 @@ static int data_callback( void* data ) {
 
 		*nl = '\0';
 
-		if ( NULL == context->headers ) {
+		if ( NULL == context->columns ) {
 
 			parse_headers( context );
 
@@ -397,7 +459,7 @@ static int data_callback( void* data ) {
 
 static void parse_headers( struct context* context ) {
 
-	assert( NULL == context->headers );
+	assert( NULL == context->columns );
 
 	const char* c = context->read_buffer;
 	char quote = '\0';
@@ -409,7 +471,7 @@ static void parse_headers( struct context* context ) {
 	if ( '\0' == *c ) {
 		return;
 	}
-	context->n_headers = 1;
+	context->n_columns = 1;
 
 	while ( '\0' != *c ) {
 
@@ -419,7 +481,7 @@ static void parse_headers( struct context* context ) {
 				c++;
 			}
 			if ( '\0' != *c ) {
-				context->n_headers++;
+				context->n_columns++;
 			}
 		} else if ( '"' == *c && '\0' == quote ) {
 			quote = '"';
@@ -439,15 +501,16 @@ static void parse_headers( struct context* context ) {
 
 	}
 
-	context->headers = calloc(
-		context->n_headers, sizeof *( context->headers ) );
+	context->columns = calloc(
+		context->n_columns, sizeof *( context->columns ) );
+	context->n_data_columns = 0;
 
 	size_t n = 0;
 	char header[strlen( context->read_buffer )];
 	c = context->read_buffer;
 	quote = '\0';
 
-	bool found = false;
+	bool xfound = false;
 
 	while ( '\0' != *c ) {
 
@@ -516,18 +579,43 @@ static void parse_headers( struct context* context ) {
 		if ( NULL != context->xaxis &&
 				0 == strcmp( stripped_header, context->xaxis ) ) {
 
-			found = true;
+			xfound = true;
+			context->columns[n].type = XAXIS;
 
 		} else {
 
-			context->headers[n] = strdup( stripped_header );
-			n++;
+			context->columns[n].type = LEFT_AXIS;
+
+			for ( struct column_list* item = context->left_columns;
+					NULL != item;
+					item = item->next ) {
+				if ( 0 == strcmp( stripped_header, item->header ) ) {
+					context->columns[n].type = RIGHT_AXIS;
+					break;
+				}
+			}
+
+			for ( struct column_list* item = context->ignore_columns;
+					NULL != item;
+					item = item->next ) {
+				if ( 0 == strcmp( stripped_header, item->header ) ) {
+					context->columns[n].type = IGNORE;
+					break;
+				}
+			}
+
+			if ( IGNORE != context->columns[n].type ) {
+				context->n_data_columns++;
+			}
 
 		}
 
+		context->columns[n].header = strdup( stripped_header );
+		n++;
+
 	}
 
-	if ( !found ) {
+	if ( !xfound ) {
 		free( context->xaxis );
 		context->xaxis = NULL;
 		context->xaxis_n = -1;
@@ -537,7 +625,7 @@ static void parse_headers( struct context* context ) {
 
 static void parse_data( struct context* context ) {
 
-	assert( 0 != context->n_headers );
+	assert( 0 != context->n_columns );
 
 	const char* c = context->read_buffer;
 	while ( ' ' == *c || '\t' == *c ) {
@@ -549,7 +637,7 @@ static void parse_data( struct context* context ) {
 	}
 
 	struct data* data = calloc( 1, sizeof (struct data) +
-		context->n_headers * sizeof *( data->y ) );
+		context->n_data_columns * sizeof *( data->y ) );
 
 	struct timespec now;
 	clock_gettime( CLOCK_MONOTONIC, &now );
@@ -558,11 +646,11 @@ static void parse_data( struct context* context ) {
 	data->x += ( now.tv_nsec - context->start_time.tv_nsec ) / 1E9;
 
 	size_t n = 0;
+	size_t data_n = 0;
 	char value[strlen( context->read_buffer )];
 	char quote = '\0';
-	bool timed = false;
 
-	while ( '\0' != *c && n < context->n_headers ) {
+	while ( '\0' != *c && n < context->n_columns ) {
 
 		value[0] = '\0';
 
@@ -628,9 +716,8 @@ static void parse_data( struct context* context ) {
 		char* end_ptr = NULL;
 		double value = strtod( stripped_value, &end_ptr );
 
-		if ( n == context->xaxis_n && !timed ) {
+		if ( XAXIS == context->columns[n].type ) {
 
-			timed = true;
 			if ( '\0' == *end_ptr ) {
 				data->x = value;
 			} else {
@@ -639,19 +726,23 @@ static void parse_data( struct context* context ) {
 			}
 
 
-		} else {
+		} else if ( IGNORE != context->columns[n].type ) {
 
 			if ( '\0' == *end_ptr ) {
-				data->y[n].v = value;
-				data->y[n].present = true;
+				data->y[data_n].v = value;
+				data->y[data_n].present = true;
+				data->y[data_n].axis =
+					LEFT_AXIS == context->columns[n].type ?
+						LEFT : RIGHT;
 			} else {
-				data->y[n].present = false;
+				data->y[data_n].present = false;
 			}
-
-			n++;
+			data_n++;
 
 		}
 
+		n++;
+
 	}
 
 	if ( NULL == context->data ) {
@@ -709,6 +800,8 @@ static void plot_draw( GtkDrawingArea* plot,
 	cairo_move_to( cr, width - 5, height - 5 );
 	cairo_line_to( cr, 5, height - 5 );
 	cairo_line_to( cr, 5, 5 );
+	cairo_line_to( cr, width - 5, 5 );
+	cairo_line_to( cr, width - 5, height - 5 );
 	cairo_stroke( cr );
 	cairo_restore( cr );
 
@@ -719,8 +812,10 @@ static void plot_draw( GtkDrawingArea* plot,
 	/* Ranges */
 
 	double xrange[2] = { context->data->x, };
-	double yrange[2];
-	bool set = false;
+	double yrrange[2];
+	double ylrange[2];
+	bool lset = false;
+	bool rset = false;
 
 	for ( struct data* data = context->data;
 			NULL != data;
@@ -728,27 +823,43 @@ static void plot_draw( GtkDrawingArea* plot,
 
 		xrange[1] = data->x;
 
-		for ( size_t i = 0; i < context->n_headers; i++ ) {
+		for ( size_t i = 0; i < context->n_data_columns; i++ ) {
 
 			if ( !data->y[i].present ) {
 				continue;
 			}
 
-			if ( !set || data->y[i].v < yrange[0] ) {
-				yrange[0] = data->y[i].v;
-			}
+			if ( data->y[i].axis == LEFT ) {
 
-			if ( !set || data->y[i].v > yrange[1] ) {
-				yrange[1] = data->y[i].v;
-			}
+				if ( !lset || data->y[i].v < ylrange[0] ) {
+					ylrange[0] = data->y[i].v;
+				}
+
+				if ( !lset || data->y[i].v > ylrange[1] ) {
+					ylrange[1] = data->y[i].v;
+				}
+
+				lset = true;
 
-			set = true;
+			} else {
+
+				if ( !rset || data->y[i].v < yrrange[0] ) {
+					yrrange[0] = data->y[i].v;
+				}
+
+				if ( !lset || data->y[i].v > yrrange[1] ) {
+					yrrange[1] = data->y[i].v;
+				}
+
+				rset = true;
+
+			}
 
 		}
 
 	}
 
-	if ( !set ) {
+	if ( !lset && !rset ) {
 		return;
 	}
 
@@ -792,9 +903,14 @@ static void plot_draw( GtkDrawingArea* plot,
 		xrange[1] += 0.5;
 	}
 
-	if ( yrange[0] == yrange[1] ) {
-		yrange[0] -= 0.5;
-		yrange[1] += 0.5;
+	if ( ylrange[0] == ylrange[1] ) {
+		ylrange[0] -= 0.5;
+		ylrange[1] += 0.5;
+	}
+
+	if ( yrrange[0] == yrrange[1] ) {
+		yrrange[0] -= 0.5;
+		yrrange[1] += 0.5;
 	}
 
 	if ( context->xfit ) {
@@ -814,12 +930,15 @@ static void plot_draw( GtkDrawingArea* plot,
 		cairo_save( cr );
 		cairo_set_source_rgb( cr, 0, 0, 0 );
 
-		for ( size_t i = 0; i < context->n_headers; i++ ) {
+		for ( size_t i = 0; i < context->n_data_columns; i++ ) {
 
 			if ( !context->data->y[i].present ) {
 				return;
 			}
 
+			double* yrange = context->data->y[i].axis == LEFT ?
+				ylrange : yrrange;
+
 			cairo_rectangle( cr, width / 2 - 1,
 				height - 5 - ( height - 10 ) *
 					( context->data->y[i].v - yrange[0] ) /
@@ -847,13 +966,16 @@ static void plot_draw( GtkDrawingArea* plot,
 			NULL != data->next;
 			data = data->next ) {
 
-		for ( size_t i = 0; i < context->n_headers; i++ ) {
+		for ( size_t i = 0; i < context->n_data_columns; i++ ) {
 
 			size_t c = i % context->n_colours;
 
 			cairo_set_source_rgb( cr, context->colours[c][0],
 				context->colours[c][1], context->colours[c][2] );
 
+			double* yrange = context->data->y[i].axis == LEFT ?
+				ylrange : yrrange;
+
 			if ( data->y[i].present ) {
 
 				if ( data->next->y[i].present ) {