diff --git a/uk/ac/sanger/artemis/components/Plot.java b/uk/ac/sanger/artemis/components/Plot.java
index b5a726915d514c500e50e94def7f14827dda16cb..175832128117d16e0d85edf50e66e3b67e3f612a 100644
--- a/uk/ac/sanger/artemis/components/Plot.java
+++ b/uk/ac/sanger/artemis/components/Plot.java
@@ -930,7 +930,7 @@ public abstract class Plot extends JPanel
    * @param NUMBER_OF_SHADES
    * @return
    */
-  protected Color[] makeColours(Color col, int NUMBER_OF_SHADES)
+  public static Color[] makeColours(Color col, int NUMBER_OF_SHADES)
   {
     Color definedColour[] = new Color[NUMBER_OF_SHADES];
     for(int i = 0; i < NUMBER_OF_SHADES; ++i)
diff --git a/uk/ac/sanger/artemis/components/alignment/AbstractGraphPanel.java b/uk/ac/sanger/artemis/components/alignment/AbstractGraphPanel.java
index 9f651b952c224c2165f1eb87abc1fc3944c29335..1f53fe42e48a02f0e8769c767cb3cbb5d6c7a639 100644
--- a/uk/ac/sanger/artemis/components/alignment/AbstractGraphPanel.java
+++ b/uk/ac/sanger/artemis/components/alignment/AbstractGraphPanel.java
@@ -161,6 +161,18 @@ public class AbstractGraphPanel extends JPanel
     g2.drawString(maxStr, xpos, fm.getHeight());
   }
   
+  /**
+   * Return the log value if the log scale is selected
+   * @param val
+   * @return
+   */
+  protected float getValue(int val)
+  {
+    if(val == 0)
+      return 0.f;
+    return (float) (bamView.logScale ? Math.log(val) : val);
+  }
+  
   protected void drawSelectionRange(final Graphics2D g2,
                                     final float pixPerBase, 
                                     final int start,
diff --git a/uk/ac/sanger/artemis/components/alignment/BamView.java b/uk/ac/sanger/artemis/components/alignment/BamView.java
index 19d8734db49ed791c2e3eb97a6382c897c8b0be0..be26ccb51dd06460dbd098b89afdaa398e385aa1 100644
--- a/uk/ac/sanger/artemis/components/alignment/BamView.java
+++ b/uk/ac/sanger/artemis/components/alignment/BamView.java
@@ -184,7 +184,7 @@ public class BamView extends JPanel
   private CoveragePanel coveragePanel;
   private SnpPanel snpPanel;
 
-  private boolean logScale = false;
+  protected boolean logScale = false;
   private Ruler ruler;
   private int nbasesInView;
   
@@ -205,6 +205,7 @@ public class BamView extends JPanel
   private JCheckBoxMenuItem cbIsizeStackView = new JCheckBoxMenuItem("Inferred Size", false);
   private JCheckBoxMenuItem cbCoverageView = new JCheckBoxMenuItem("Coverage", false);
   private JCheckBoxMenuItem cbCoverageStrandView = new JCheckBoxMenuItem("Coverage by Strand", false);
+  private JCheckBoxMenuItem cbCoverageHeatMap = new JCheckBoxMenuItem("Coverage Heat Map", false);
   private JCheckBoxMenuItem cbLastSelected;
   
   private ButtonGroup buttonGroup = new ButtonGroup();
@@ -354,6 +355,7 @@ public class BamView extends JPanel
     buttonGroup.add(cbIsizeStackView);
     buttonGroup.add(cbCoverageView);
     buttonGroup.add(cbCoverageStrandView);
+    buttonGroup.add(cbCoverageHeatMap);
     addMouseListener(new PopupListener());
 
     jspView = new JScrollPane(this, 
@@ -1807,7 +1809,7 @@ public class BamView extends JPanel
     }
 
     int hgt = jspView.getVisibleRect().height-scaleHeight;
-    if(!cbCoverageStrandView.isSelected())
+    if(!cbCoverageStrandView.isSelected() && !cbCoverageHeatMap.isSelected())
     {
       try
       {
@@ -1819,7 +1821,8 @@ public class BamView extends JPanel
       catch(Exception e){}
     }
 
-    g2.translate(0, getHeight()-hgt-scaleHeight);
+    g2.translate(0, getJspView().getViewport().getViewPosition().y);
+
     coverageView.drawSelectionRange(g2, pixPerBase, start, end, getHeight(), Color.PINK);
     coverageView.draw(g2, getWidth(), hgt);
     coverageView.drawMax(g2);  
@@ -2519,6 +2522,7 @@ public class BamView extends JPanel
     cbStrandStackView.setFont(viewMenu.getFont());
     cbCoverageView.setFont(viewMenu.getFont());
     cbCoverageStrandView.setFont(viewMenu.getFont());
+    cbCoverageHeatMap.setFont(viewMenu.getFont());
     
     baseQualityColour.setFont(viewMenu.getFont());
     colourByCoverageColour.setFont(viewMenu.getFont());
@@ -2530,6 +2534,7 @@ public class BamView extends JPanel
       {
         laststart = -1;
         logMenuItem.setEnabled(isIsizeStackView());
+        getJspView().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
         repaint();
       }
     });
@@ -2541,7 +2546,9 @@ public class BamView extends JPanel
       public void actionPerformed(ActionEvent e)
       {
         laststart = -1;
-        logMenuItem.setEnabled(isIsizeStackView());
+        if(cbStackView.isSelected())
+          logMenuItem.setEnabled(false);
+        getJspView().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
         repaint();
       }
     });
@@ -2553,7 +2560,9 @@ public class BamView extends JPanel
       public void actionPerformed(ActionEvent e)
       {
         laststart = -1;
-        logMenuItem.setEnabled(isIsizeStackView());
+        if(cbPairedStackView.isSelected())
+          logMenuItem.setEnabled(false);
+        getJspView().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
         repaint();
       }
     });
@@ -2567,7 +2576,9 @@ public class BamView extends JPanel
         if(isStrandStackView())
           setViewportMidPoint();
 
-        logMenuItem.setEnabled(isIsizeStackView());
+        if(cbStrandStackView.isSelected())
+          logMenuItem.setEnabled(false);
+        getJspView().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
         repaint();
       }
     });
@@ -2578,11 +2589,13 @@ public class BamView extends JPanel
       public void actionPerformed(ActionEvent e)
       {
         laststart = -1;
-        logMenuItem.setEnabled(isIsizeStackView());
         if(cbCoverageView.isSelected())
         {
+          logMenuItem.setEnabled(true);
+          coverageView.setPlotHeatMap(false);
           coverageView.setPlotByStrand(false);
           setViewportBtm();
+          getJspView().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
         }
         repaint();
       }
@@ -2594,17 +2607,39 @@ public class BamView extends JPanel
       public void actionPerformed(ActionEvent e)
       {
         laststart = -1;
-        logMenuItem.setEnabled(isIsizeStackView());
         if(cbCoverageStrandView.isSelected())
         {
+          logMenuItem.setEnabled(true);
+          coverageView.setPlotHeatMap(false);
           coverageView.setPlotByStrand(true);
           setViewportBtm();
+          getJspView().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
         }
+
         repaint();
       }
     });
     viewMenu.add(cbCoverageStrandView);
     
+    
+    cbCoverageHeatMap.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        laststart = -1;
+        if(cbCoverageHeatMap.isSelected())
+        {
+          logMenuItem.setEnabled(true);
+          coverageView.setPlotHeatMap(true);
+          setViewportBtm();
+          getJspView().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
+        }
+
+        repaint();
+      }
+    });
+    viewMenu.add(cbCoverageHeatMap);
+    
     menu.add(viewMenu);
  
     final JCheckBoxMenuItem checkBoxSNPs = new JCheckBoxMenuItem("SNP marks");
@@ -2692,7 +2727,8 @@ public class BamView extends JPanel
         
         if( isCoverage && 
             !cbCoverageView.isSelected() && 
-            !cbCoverageStrandView.isSelected() )
+            !cbCoverageStrandView.isSelected() &&
+            !cbCoverageHeatMap.isSelected())
           laststart = -1;
         repaint();
       }
@@ -2825,6 +2861,8 @@ public class BamView extends JPanel
             feature_display, bases, (JPanel) mainPanel.getParent(), null);
         bamView.getJspView().getVerticalScrollBar().setValue(
             bamView.getJspView().getVerticalScrollBar().getMaximum());
+        getJspView().getVerticalScrollBar().setValue(
+            bamView.getJspView().getVerticalScrollBar().getMaximum());
 
         int start = getBaseAtStartOfView();
         setDisplay(start, nbasesInView+start, null);
@@ -3124,13 +3162,13 @@ public class BamView extends JPanel
     }
     else if(jspView != null)
     {
-      if(!cbCoverageView.isSelected() && !cbCoverageStrandView.isSelected() && nbasesInView >= MAX_BASES)
+      if(isCoverageView(pixPerBase) && nbasesInView >= MAX_BASES)
       {
         cbLastSelected = getSelectedCheckBoxMenuItem();
         cbCoverageView.setSelected(true);
         coverageView.setPlotByStrand(false);
       }
-      else if((cbCoverageView.isSelected() || cbCoverageStrandView.isSelected()) && nbasesInView < MAX_BASES && cbLastSelected != null)
+      else if(isCoverageView(pixPerBase) && nbasesInView < MAX_BASES && cbLastSelected != null)
       {
         cbLastSelected.setSelected(true);
         cbLastSelected = null;
@@ -3358,7 +3396,7 @@ public class BamView extends JPanel
   {
     if(isBaseAlignmentView(pixPerBase))
       return false;
-    return cbCoverageView.isSelected() || cbCoverageStrandView.isSelected();
+    return cbCoverageView.isSelected() || cbCoverageStrandView.isSelected() || cbCoverageHeatMap.isSelected();
   }
   
   private boolean isIsizeStackView()
@@ -3385,6 +3423,8 @@ public class BamView extends JPanel
       return cbIsizeStackView;
     if(cbCoverageView.isSelected())
       return cbCoverageView;
+    if(cbCoverageHeatMap.isSelected())
+      return cbCoverageHeatMap;
     return cbCoverageStrandView;
   }
   
diff --git a/uk/ac/sanger/artemis/components/alignment/CoveragePanel.java b/uk/ac/sanger/artemis/components/alignment/CoveragePanel.java
index 6e29e5b8f889116805a6f000f8688a7c2f0493fc..ffd7bd4e0ea917ee01645654f383f73c4723a255 100644
--- a/uk/ac/sanger/artemis/components/alignment/CoveragePanel.java
+++ b/uk/ac/sanger/artemis/components/alignment/CoveragePanel.java
@@ -45,6 +45,8 @@ import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JTextField;
 
+import uk.ac.sanger.artemis.components.Plot;
+
 import net.sf.samtools.AlignmentBlock;
 import net.sf.samtools.SAMRecord;
 
@@ -60,6 +62,7 @@ import net.sf.samtools.SAMRecord;
     private boolean setMaxBases = false;
     
     private boolean plotByStrand = false;
+    private boolean plotHeatMap = false;
 
     protected CoveragePanel(final BamView bamView)
     {
@@ -115,7 +118,8 @@ import net.sf.samtools.SAMRecord;
       if(plots == null)
         return;
 
-      drawSelectionRange(g2, pixPerBase, start, end, getHeight(), Color.PINK);
+      if(!plotHeatMap)
+        drawSelectionRange(g2, pixPerBase, start, end, getHeight(), Color.PINK);
       drawPlot(g2);
       drawMax(g2);
     }
@@ -175,6 +179,7 @@ import net.sf.samtools.SAMRecord;
             max = thisPlot[i][0];
         }
       }
+      
       draw(g2, getWidth(), getHeight());
     }
     
@@ -232,7 +237,6 @@ import net.sf.samtools.SAMRecord;
       else
         lines = getLineAttributes(size);
 
-      int hgt2 = hgt/2;
 
       Enumeration<String> plotEum = plots.keys();
       while(plotEum.hasMoreElements())
@@ -245,86 +249,97 @@ import net.sf.samtools.SAMRecord;
           index = lines.length-1;
         else
           index = bamView.bamList.indexOf(fileName);
-        
-        g2.setColor(lines[index].getLineColour());
-        if(lines[index].getPlotType() == LineAttributes.PLOT_TYPES[0])
+
+        if(plotHeatMap)
+          drawHeatMap(g2, hgt, index, thisPlot);
+        else
+          drawLinePlot(g2, wid, hgt, index, thisPlot);
+      }
+    }
+    
+    private void drawLinePlot(final Graphics2D g2, int wid, int hgt, int index, int[][] thisPlot)
+    {
+      g2.setColor(lines[index].getLineColour());
+      int hgt2 = hgt/2;
+      float maxVal = getValue(max);
+      
+      if(lines[index].getPlotType() == LineAttributes.PLOT_TYPES[0])
+      {
+        g2.setStroke(lines[index].getStroke());
+        for(int i=1; i<thisPlot.length; i++)
         {
-          g2.setStroke(lines[index].getStroke());
-          for(int i=1; i<thisPlot.length; i++)
+          int x0 = (int) ((((i-1)*(windowSize)) - windowSize/2.f)*pixPerBase);
+          int x1 = (int) (((i*(windowSize)) - windowSize/2.f)*pixPerBase);
+          int y0, y1;
+          if(plotByStrand)
           {
-            int x0 = (int) ((((i-1)*(windowSize)) - windowSize/2.f)*pixPerBase);
-            int x1 = (int) (((i*(windowSize)) - windowSize/2.f)*pixPerBase);
-            int y0, y1;
-            if(plotByStrand)
-            {
-              for(int col=0; col<2; col++)
-              {
-                final int factor;
-                if(col == 0)
-                  factor = 1;   // fwd strand
-                else
-                  factor = -1;  // reverse strand
-                
-                y0 = (int) (hgt2 - (factor)*(((float)thisPlot[i-1][col]/(float)max)*hgt2));
-                y1 = (int) (hgt2 - (factor)*(((float)thisPlot[i][col]/(float)max)*hgt2));
-                
-                g2.drawLine(x0, y0, x1, y1);
-              }
-            }
-            else
+            for(int col=0; col<2; col++)
             {
-              y0 = (int) (hgt - (((float)(thisPlot[i-1][0])/(float)max)*hgt));
-              y1 = (int) (hgt - (((float)(thisPlot[i][0])/(float)max)*hgt));
+              final int factor;
+              if(col == 0)
+                factor = 1;   // fwd strand
+              else
+                factor = -1;  // reverse strand
+              
+              y0 = (int) (hgt2 - (factor)*((getValue(thisPlot[i-1][col])/maxVal)*hgt2));
+              y1 = (int) (hgt2 - (factor)*((getValue(thisPlot[i][col])/maxVal)*hgt2));
+              
               g2.drawLine(x0, y0, x1, y1);
             }
           }
+          else
+          {
+            y0 = (int) (hgt - ((getValue(thisPlot[i-1][0])/maxVal)*hgt));
+            y1 = (int) (hgt - ((getValue(thisPlot[i][0])/maxVal)*hgt));
+            g2.drawLine(x0, y0, x1, y1);
+          }
         }
-        else // filled plots
-        {
-          g2.setComposite(makeComposite(0.75f));
+      }
+      else // filled plots
+      {
+        g2.setComposite(makeComposite(0.75f));
 
-          if(plotByStrand)
+        if(plotByStrand)
+        {
+          final GeneralPath shapeFwd = new GeneralPath();
+          shapeFwd.moveTo(0,hgt2);
+          final  GeneralPath shapeBwd = new GeneralPath();
+          shapeBwd.moveTo(0,hgt2);
+        
+          for(int i=0; i<thisPlot.length; i++)
           {
-            final GeneralPath shapeFwd = new GeneralPath();
-            shapeFwd.moveTo(0,hgt2);
-            final  GeneralPath shapeBwd = new GeneralPath();
-            shapeBwd.moveTo(0,hgt2);
-          
-            for(int i=0; i<thisPlot.length; i++)
+            float xpos = ((i*(windowSize)) - windowSize/2.f)*pixPerBase;
+            for(int col=0; col<2; col++)
             {
-              float xpos = ((i*(windowSize)) - windowSize/2.f)*pixPerBase;
-              for(int col=0; col<2; col++)
-              {
-                if(col == 0)
-                  shapeFwd.lineTo(xpos,
-                    hgt2 - (((float)thisPlot[i][col]/(float)max)*hgt2));
-                else
-                  shapeBwd.lineTo(xpos,
-                    hgt2 + (((float)thisPlot[i][col]/(float)max)*hgt2));
-              }
+              if(col == 0)
+                shapeFwd.lineTo(xpos,
+                  hgt2 - ((getValue(thisPlot[i][col])/maxVal)*hgt2));
+              else
+                shapeBwd.lineTo(xpos,
+                  hgt2 + ((getValue(thisPlot[i][col])/maxVal)*hgt2));
             }
-
-            shapeBwd.lineTo(wid,hgt2);
-            shapeFwd.lineTo(wid,hgt2);
-            g2.fill(shapeBwd);
-            g2.fill(shapeFwd);
           }
-          else
+
+          shapeBwd.lineTo(wid,hgt2);
+          shapeFwd.lineTo(wid,hgt2);
+          g2.fill(shapeBwd);
+          g2.fill(shapeFwd);
+        }
+        else
+        {
+          final GeneralPath shape = new GeneralPath();
+          shape.moveTo(0,hgt);
+          for(int i=0; i<thisPlot.length; i++)
           {
-            final GeneralPath shape = new GeneralPath();
-            shape.moveTo(0,hgt);
-            for(int i=0; i<thisPlot.length; i++)
-            {
-              float xpos = ((i*(windowSize)) - windowSize/2.f)*pixPerBase;
-              shape.lineTo(xpos,
-                  hgt - (((float)thisPlot[i][0]/(float)max)*hgt));
-            }
-            shape.lineTo(wid,hgt);
-            g2.fill(shape);
+            float xpos = ((i*(windowSize)) - windowSize/2.f)*pixPerBase;
+            shape.lineTo(xpos,
+                hgt - ((getValue(thisPlot[i][0])/maxVal)*hgt));
           }
+          shape.lineTo(wid,hgt);
+          g2.fill(shape);
         }
       }
-
+      
       if(plotByStrand)
       {
         g2.setColor(Color.GRAY);
@@ -332,6 +347,42 @@ import net.sf.samtools.SAMRecord;
       }
     }
     
+    /**
+     * Draw as heat map
+     * @param g2
+     * @param hgt
+     * @param index
+     * @param thisPlot
+     */
+    private void drawHeatMap(final Graphics2D g2, int hgt, int index, int[][] thisPlot)
+    { // heat map
+      int NUMBER_OF_SHADES = 254;
+      int plotHgt = hgt/plots.size();
+      int plotPos = plotHgt * index;
+      Color definedColours[] = Plot.makeColours(lines[index].getLineColour(),
+          NUMBER_OF_SHADES);
+      
+      float maxVal = getValue(max);
+      for(int i=0; i<thisPlot.length; i++)
+      {
+        int xpos = (int) ((((i-1)*(windowSize)) - windowSize/2.f)*pixPerBase);
+
+        // this is a number between 0.0 and 1.0
+        final float scaledValue = getValue(thisPlot[i][0]) / maxVal;
+        // set color based on value
+        int colourIndex = 
+          (int)(definedColours.length * 0.999 * scaledValue);
+
+        if(colourIndex > definedColours.length - 1)
+          colourIndex = definedColours.length - 1;
+        else if (colourIndex < 0)
+          colourIndex = 0;
+        
+        g2.setColor(definedColours[ colourIndex ]);
+        g2.fillRect(xpos, plotPos, windowSize, plotHgt);
+      }
+    }
+    
     private AlphaComposite makeComposite(float alpha)
     {
       int type = AlphaComposite.SRC_OVER;
@@ -374,6 +425,14 @@ import net.sf.samtools.SAMRecord;
       this.plotByStrand = plotByStrand;
     }
     
+    /**
+     * @param plotHeatMap the plotHeatMap to set
+     */
+    protected void setPlotHeatMap(boolean plotHeatMap)
+    {
+      this.plotHeatMap = plotHeatMap;
+    }
+
     private void defineOpts()
     {
       final JPanel opts = new JPanel(new GridBagLayout());