diff --git a/src/main.c b/src/main.c
index 2a2068920daf4b375c0026c3d190799d29b3d350..2a5b73cca71055d4a41654d1e54995e1f5273082 100644
--- a/src/main.c
+++ b/src/main.c
@@ -91,6 +91,7 @@ static void parse_headers( struct context* context );
 static void parse_data( struct context* context );
 static void plot_draw( GtkDrawingArea* plot,
 	cairo_t* cr, int width, int height, void* data );
+static int pretty( double* lo, double* up, int ndiv );
 
 /* PUBLIC FUNK!!! */
 
@@ -917,6 +918,10 @@ static void plot_draw( GtkDrawingArea* plot,
 		context->xdist = xrange[1] - xrange[0];
 	}
 
+	int xdivs = pretty( &( xrange[0] ), &( xrange[1] ), 10 );
+	int yldivs = pretty( &( ylrange[0] ), &( ylrange[1] ), 10 );
+	int yrdivs = pretty( &( yrrange[0] ), &( yrrange[1] ), 10 );
+
 	/* Data */
 
 	struct data* first_data = context->data;
@@ -1018,4 +1023,138 @@ static void plot_draw( GtkDrawingArea* plot,
 
 	cairo_restore( cr );
 
+	cairo_save( cr );
+
+	for ( int i = 0; i < xdivs; i++ ) {
+		cairo_move_to( cr,
+			5 + i * ( width - 10 ) / ( xdivs - 1 ),
+			height - 5 );
+		cairo_line_to( cr,
+			5 + i * ( width - 10 ) / ( xdivs - 1 ),
+			height - 2 );
+		cairo_stroke( cr );
+	}
+
+	for ( int i = 0; i < yldivs && lset; i++ ) {
+		cairo_move_to( cr,
+			2,
+			5 + i * ( height - 10 ) / ( yldivs - 1 ) );
+		cairo_line_to( cr,
+			5,
+			5 + i * ( height - 10 ) / ( yldivs - 1 ) );
+		cairo_stroke( cr );
+	}
+
+	for ( int i = 0; i < yrdivs && rset; i++ ) {
+		cairo_move_to( cr,
+			width - 5,
+			5 + i * ( height - 10 ) / ( yrdivs - 1 ) );
+		cairo_line_to( cr,
+			width - 2,
+			5 + i * ( height - 10 ) / ( yrdivs - 1 ) );
+		cairo_stroke( cr );
+	}
+
+}
+
+static int pretty( double* lo, double* up, int ndiv ) {
+
+	/* Shamelessly filched from the R language's source code.
+	 * (src/appl/pretty.c) */
+
+#define rounding_eps 1E-10
+#define h 1.5
+#define h5 ( .5 + 1.5 * h )
+#define shrink_sml 0.75
+#define f_min 2E-20
+#define MAX_F  1.25
+
+	double lo_ = *lo;
+	double up_ = *up;
+
+	double dx = up_ - lo_;
+	double cell = fabs( lo_ ) > fabs( up_ ) ? fabs( lo_ ) : fabs( up_ );
+	double U = 1 + ( ( h5 >= 1.5 * h + 0.5 ) ?
+		1 / ( 1 + h ) : 1.5 / ( 1 + h5 ) );
+	U *= ndiv * DBL_EPSILON;
+	bool i_small = dx < cell * U * 3;
+
+	if ( i_small ) {
+
+		if ( cell > 10 ) {
+			cell = 9 + cell / 10;
+		}
+		cell *= shrink_sml;
+
+	} else {
+
+		cell = dx;
+		if ( 1 < ndiv ) {
+			cell /= ndiv;
+		}
+
+	}
+
+	double subsmall = f_min * DBL_MIN;
+	if ( subsmall == 0. ) {
+		subsmall = DBL_MIN;
+	}
+	if ( cell < subsmall ) {
+		cell = subsmall;
+	} else if ( cell > DBL_MAX / MAX_F ) {
+		cell = DBL_MAX / MAX_F;
+	}
+
+	double base = pow( 10.0, floor( log10( cell ) ) );
+	double unit = base;
+	if ( ( U = 2 * base ) - cell < h * ( cell - unit ) ) {
+		unit = U;
+		if ( ( U = 5 * base ) - cell < h5 * ( cell - unit ) ) {
+			unit = U;
+			if ( ( U = 10 * base ) - cell < h * ( cell - unit ) ) {
+				unit = U;
+			}
+		}
+	}
+
+	double ns = floor( lo_ / unit + rounding_eps );
+	double nu = ceil( up_ / unit - rounding_eps );
+
+	while ( ns * unit > *lo + rounding_eps * unit ) {
+		ns--;
+	}
+
+	while ( nu * unit < *up - rounding_eps * unit ) {
+		nu++;
+	}
+
+	int k = (int) ( .5 + nu - ns );
+	if ( k < 1 ) {
+		k = 1 - k;
+
+		if ( lo_ == 0. && ns == 0. && up_ != 0. ) {
+			nu += k;
+		} else if ( up_ == 0. && nu == 0. && lo_ != 0. ) {
+			ns -= k;
+		} else if ( ns >= 0. ) {
+			nu += k / 2;
+			ns -= k / 2 + k % 2;
+		} else {
+			ns -= k / 2;
+			nu += k / 2 + k % 2;
+		}
+		ndiv = 1;
+	} else {
+		ndiv = k;
+	}
+
+	if ( ns * unit < *lo ) {
+		*lo = ns * unit;
+	}
+	if ( nu * unit > *up ) {
+		*up = nu * unit;
+	}
+
+	return ndiv;
+
 }