diff --git a/src/spectrogram.c b/src/spectrogram.c
index fd29a0f..589343e 100644
--- a/src/spectrogram.c
+++ b/src/spectrogram.c
@@ -24,7 +24,6 @@
 **      - Make magnitude to colour mapper allow abitrary scaling (ie cmdline
 **        arg).
 **      - Better cmdline arg parsing and flexibility.
-**      - Add option to do log frequency scale.
 */
 
 #include <stdlib.h>
@@ -251,8 +250,8 @@ y_line (cairo_t * cr, double x, double y, double len)
 /* The greatest number of ticks seems to occurs from 0-14000 (15 ticks).
 ** Play safe with 20. */
 typedef struct
-{	double value [20] ;
-	double distance [20] ;
+{	double value [200] ;
+	double distance [200] ;
 	/* The digit that changes from label to label.
 	** This ensures that a range from 999 to 1001 prints 999.5 and 1000.5
 	** instead of 999 1000 1000 1000 1001.
@@ -293,14 +292,21 @@ typedef struct
 */
 #define DELTA (1e-10)
 
-static inline int
-calculate_ticks (double min, double max, double distance, TICKS * ticks)
+static int	/* Forward declaration */
+calculate_log_ticks (double min, double max, double distance, TICKS * ticks);
+
+static int
+calculate_ticks (double min, double max, double distance, bool log_scale, TICKS * ticks)
 {
 	double step ;   /* Put numbered ticks at multiples of this */
 	double range = max - min ;
 	int k ;
 	double value ;  /* Temporary */
 
+	if (log_scale) return calculate_log_ticks (min, max, distance, ticks);
+
+	/* Linear version */
+
 	/* Choose a step between successive axis labels so that one digit
 	** changes by 1, 2 or 5 amd that gives us at least the number of
 	** divisions (and numberic labels) that we would like to have.
@@ -358,7 +364,90 @@ calculate_ticks (double min, double max, double distance, TICKS * ticks)
 		} ;
 
 	return k ;
-}
+} /* calculate_ticks */
+
+/* Number/tick placer for logarithmic scales.
+**
+** Some say we should number 1, 10, 100, 1000, 1000 and place ticks at
+** 2,3,4,5,6,7,8,9, 20,30,40,50,60,70,80,90, 200,300,400,500,600,700,800,900
+** Others suggest numbering 1,2,5, 10,20,50, 100,200,500.
+**
+** Ticking 1-9 is visually distinctive and emphasizes that we are using
+** a log scale, as well as mimicking log graph paper.
+** Numbering the powers of ten and, if that doesn't give enough labels,
+** numbering also the 2 and 5 multiples might work.
+**
+** Apart from our [number] and tick styles:
+** [1] 2 5 [10] 20 50 [100]  and
+** [1] [2] 3 4 [5] 6 7 8 9 [10]
+** the following are also seen in use:
+** [1] [2] 3 4 [5] 6 7 [8] 9 [10]  and
+** [1] [2] [3] [4] [5] [6] 7 [8] 9 [10]
+** in https://www.lhup.edu/~dsimanek/scenario/errorman/graphs2.htm
+**
+** This works fine for wide ranges, not so well for narrow ranges like
+** 5000-6000.
+**
+** How should we number/tick ranges less than a power of ten, like 1080 to 1280?
+** should we label 1100 1120 1150 1200?
+**
+** Alternatives could be:
+** - by powers or two from some starting frequency
+**   defaulting to the Nyquist frequency (22050, 11025, 5512.5 ...) or from some
+**   musical pitch (220, 440, 880, 1760)
+** - with a musical note scale  C0 ' D0 ' E0 F0 ' G0 ' A0 ' B0 C1
+** - with manuscript staff lines, piano note or guitar string overlay.
+*/
+
+/* Helper functions: add ticks and labels at start_value and all powers of ten
+** times it that are in the min-max range.
+** This is used to plonk ticks at 1, 10, 100, 1000 then at 2, 20, 200, 2000
+** then at 5, 50, 500, 5000 and so on.
+*/
+static int
+add_log_ticks(double min, double max, double distance, TICKS * ticks,
+              int k, double start_value, bool include_number)
+{	double value;
+
+	for (value = start_value; value <= max + DELTA; value *= 10.0) {
+		if (value < min - DELTA) continue;
+		ticks->value [k] = include_number ? value : NO_NUMBER ;
+		ticks->distance [k] = distance * (log (value) - log (min)) / (log (max) - log (min)) ;
+		k++ ;
+		} ;
+	return k ;
+} /* add_log_ticks */
+
+static int
+calculate_log_ticks (double min, double max, double distance, TICKS * ticks)
+{	int k = 0 ;	/* Number of ticks we have placed in "ticks" array */
+	double underpinning ; 	/* Largest power of ten that is <= min */
+
+	/* First hack: label the powers of ten. */
+
+ 	/* Find largest power of ten that is <= minimum value */
+	underpinning = pow (10.0, floor (log10 (min))) ;
+
+	/* Go powering up by 10 from there, numbering as we go. */
+	k = add_log_ticks(min, max, distance, ticks, k, underpinning, true);
+
+	/* Do we have enough numbers? If so, add numberless ticks at 2 and 5 */
+	if (k >= TARGET_DIVISIONS + 1) /* Number of labels is n.of divisions + 1 */
+	{
+		k = add_log_ticks(min, max, distance, ticks, k, underpinning * 2.0, false);
+		k = add_log_ticks(min, max, distance, ticks, k, underpinning * 5.0, false);
+		}
+	else
+	{	int i ;
+		/* Not enough numbers: add numbered ticks at 2 and 5 and
+		 * unnumbered ticks at all the rest */
+		for (i=2; i<=9; i++)
+			k = add_log_ticks(min, max, distance, ticks, k,
+			                  underpinning * (1.0 * i), i==2 || i == 5);
+		} ;
+
+	return k ;
+} /* calculate_log_ticks */
 
 static void
 str_print_value (char * text, int text_len, double value, int decimal_places_to_print)
@@ -369,7 +458,7 @@ str_print_value (char * text, int text_len, double value, int decimal_places_to_
 } /* str_print_value */
 
 static void
-render_spect_border (cairo_surface_t * surface, const char * filename, double left, double width, double seconds, double top, double height, double min_freq, double max_freq)
+render_spect_border (cairo_surface_t * surface, const char * filename, double left, double width, double seconds, double top, double height, double min_freq, double max_freq, bool log_freq)
 {
 	char text [512] ;
 	cairo_t * cr ;
@@ -401,7 +490,7 @@ render_spect_border (cairo_surface_t * surface, const char * filename, double le
 	cairo_rectangle (cr, left, top, width, height) ;
 
 	/* Put ticks on Time axis */
-	tick_count = calculate_ticks (0.0, seconds, width, &ticks) ;
+	tick_count = calculate_ticks (0.0, seconds, width, false, &ticks) ;
 	for (k = 0 ; k < tick_count ; k++)
 	{	y_line (cr, left + ticks.distance [k], top + height, TICK_LEN) ;
 		if (JUST_A_TICK(ticks,k))
@@ -414,7 +503,7 @@ render_spect_border (cairo_surface_t * surface, const char * filename, double le
 		} ;
 
 	/* Put ticks on Frequency axis */
-	tick_count = calculate_ticks (min_freq, max_freq, height, &ticks) ;
+	tick_count = calculate_ticks (min_freq, max_freq, height, log_freq, &ticks) ;
 	for (k = 0 ; k < tick_count ; k++)
 	{	x_line (cr, left + width, top + height - ticks.distance [k], TICK_LEN) ;
 		if (JUST_A_TICK(ticks,k))
@@ -474,7 +563,7 @@ render_heat_border (cairo_surface_t * surface, double magfloor, const RECT *r)
 	cairo_move_to (cr, r->left + (r->width - extents.width) / 2, r->top - 5) ;
 	cairo_show_text (cr, decibels) ;
 
-	tick_count = calculate_ticks (0.0, fabs (magfloor), r->height, &ticks) ;
+	tick_count = calculate_ticks (0.0, fabs (magfloor), r->height, false, &ticks) ;
 	for (k = 0 ; k < tick_count ; k++)
 	{	x_line (cr, r->left + r->width, r->top + ticks.distance [k], TICK_LEN) ;
 		if (JUST_A_TICK(ticks,k))
@@ -500,9 +589,15 @@ render_heat_border (cairo_surface_t * surface, double magfloor, const RECT *r)
 ** allowing the caller to interpolate onto the input array.
 */
 static double
-magindex_to_specindex(int speclen, int maglen, int magindex, double min_freq, double max_freq, int samplerate)
+magindex_to_specindex(int speclen, int maglen, int magindex, double min_freq, double max_freq, int samplerate, bool log_freq)
 {
-	double freq = min_freq + (max_freq - min_freq) * magindex / (maglen - 1) ;
+	double freq; /* The frequency that this output value represents */
+
+	if (!log_freq)
+		freq = min_freq + (max_freq - min_freq) * magindex / (maglen - 1) ;
+	else
+		freq = min_freq * pow (max_freq / min_freq, (double) magindex / (maglen - 1)) ;
+
 	return (freq * speclen / (samplerate / 2)) ;
 }
 
@@ -531,9 +626,11 @@ interp_spec (float * mag, int maglen, const double *spec, int speclen, const REN
 	for (k = 0 ; k < maglen ; k++)
 	{	/* Average the pixels in the range it comes from */
 		double this = magindex_to_specindex(speclen, maglen, k,
-			        render->min_freq, render->max_freq, samplerate) ;
+			        render->min_freq, render->max_freq, samplerate,
+				render->log_freq) ;
 		double next = magindex_to_specindex(speclen, maglen, k+1,
-			        render->min_freq, render->max_freq, samplerate) ;
+			        render->min_freq, render->max_freq, samplerate,
+				render->log_freq) ;
 
 		/* Range check: can happen if --max-freq > samplerate / 2 */
 		if (this > speclen)
@@ -708,7 +805,7 @@ render_to_surface (const RENDER * render, SNDFILE *infile, int samplerate, sf_co
 
 		render_heat_map (surface, render->spec_floor_db, &heat_rect, render->gray_scale) ;
 
-		render_spect_border (surface, render->filename, LEFT_BORDER, width, filelen / (1.0 * samplerate), TOP_BORDER, height, render->min_freq, render->max_freq) ;
+		render_spect_border (surface, render->filename, LEFT_BORDER, width, filelen / (1.0 * samplerate), TOP_BORDER, height, render->min_freq, render->max_freq, render->log_freq) ;
 		render_heat_border (surface, render->spec_floor_db, &heat_rect) ;
 		}
 	else
@@ -760,11 +857,6 @@ render_sndfile (RENDER * render)
 	SNDFILE *infile ;
 	SF_INFO info ;
 
-	if (render->log_freq)
-	{	printf ("Error : --log-freq option not working yet.\n\n") ;
-		exit (1) ;
-		} ;
-
 	memset (&info, 0, sizeof (info)) ;
 
 	infile = sf_open (render->sndfilepath, SFM_READ, &info) ;
@@ -773,7 +865,10 @@ render_sndfile (RENDER * render)
 		exit (1) ;
 		} ;
 
-	if (render->max_freq == 0.0) render->max_freq = (double) info.samplerate / 2 ;
+	if (render->max_freq == 0.0)
+		render->max_freq = (double) info.samplerate / 2 ;
+	if (render->min_freq == 0.0 && render->log_freq)
+		render->min_freq = 20.0;
 
 	/* Do this sanity check here, as soon as max_freq has its default value */
 	if (render->min_freq >= render->max_freq)
@@ -810,7 +905,7 @@ usage_exit (const char * argv0, int error)
 		"        --no-border            : Drop the border, scales, heat map and title\n"
 		"        --min-freq=<number>    : Set the minimum frequency in the output\n"
 		"        --max-freq=<number>    : Set the maximum frequency in the output\n"
-		/*-"        --log-freq             : Use a logarithmic frquency scale\n" -*/
+		"        --log-freq             : Use a logarithmic frquency scale\n"
 		"        --gray-scale           : Output gray pixels instead of a heat map\n"
 		"        --kaiser               : Use a Kaiser window function (the default)\n"
 		"        --rectangular          : Use a rectangular window function\n"
