diff --git a/src/components/shapes/draw.js b/src/components/shapes/draw.js
index 6b51ce15461..bfcd58944d8 100644
--- a/src/components/shapes/draw.js
+++ b/src/components/shapes/draw.js
@@ -57,7 +57,7 @@ function draw(gd) {
 function drawOne(gd, index) {
     // remove the existing shape if there is one.
     // because indices can change, we need to look in all shape layers
-    gd._fullLayout._paper
+    gd._fullLayout._paperdiv
         .selectAll('.shapelayer [data-index="' + index + '"]')
         .remove();
 
diff --git a/src/components/updatemenus/draw.js b/src/components/updatemenus/draw.js
index 39efaf73cdd..6c6a470fecf 100644
--- a/src/components/updatemenus/draw.js
+++ b/src/components/updatemenus/draw.js
@@ -54,7 +54,7 @@ module.exports = function draw(gd) {
      */
 
     // draw update menu container
-    var menus = fullLayout._infolayer
+    var menus = fullLayout._menulayer
         .selectAll('g.' + constants.containerClassName)
         .data(menuData.length > 0 ? [0] : []);
 
@@ -97,6 +97,9 @@ module.exports = function draw(gd) {
 
     // remove exiting header, remove dropped buttons and reset margins
     if(headerGroups.enter().size()) {
+        // make sure gButton is on top of all headers
+        gButton.node().parentNode.appendChild(gButton.node());
+
         gButton
             .call(removeAllButtons)
             .attr(constants.menuIndexAttrName, '-1');
@@ -135,13 +138,12 @@ module.exports = function draw(gd) {
     });
 };
 
+/**
+ * get only visible menus for display
+ */
 function makeMenuData(fullLayout) {
-    var contOpts = fullLayout[constants.name],
-        menuData = [];
-
-    // Filter visible dropdowns and attach '_index' to each
-    // fullLayout options object to be used for 'object constancy'
-    // in the data join key function.
+    var contOpts = fullLayout[constants.name];
+    var menuData = [];
 
     for(var i = 0; i < contOpts.length; i++) {
         var item = contOpts[i];
@@ -154,7 +156,7 @@ function makeMenuData(fullLayout) {
 
 // Note that '_index' is set at the default step,
 // it corresponds to the menu index in the user layout update menu container.
-// Because a menu can b set invisible,
+// Because a menu can be set invisible,
 // this is a more 'consistent' field than the index in the menuData.
 function keyFunction(menuOpts) {
     return menuOpts._index;
diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js
index 75f6b092529..e4a1e83d9bb 100644
--- a/src/plot_api/plot_api.js
+++ b/src/plot_api/plot_api.js
@@ -2830,25 +2830,25 @@ function makePlotFramework(gd) {
     // single geo layer for the whole plot
     fullLayout._geolayer = fullLayout._paper.append('g').classed('geolayer', true);
 
-    // upper shape layer
-    // (only for shapes to be drawn above the whole plot, including subplots)
-    var layerAbove = fullLayout._paper.append('g')
-        .classed('layer-above', true);
-    fullLayout._imageUpperLayer = layerAbove.append('g')
-        .classed('imagelayer', true);
-    fullLayout._shapeUpperLayer = layerAbove.append('g')
-        .classed('shapelayer', true);
-
     // single pie layer for the whole plot
     fullLayout._pielayer = fullLayout._paper.append('g').classed('pielayer', true);
 
     // fill in image server scrape-svg
     fullLayout._glimages = fullLayout._paper.append('g').classed('glimages', true);
 
-    // lastly info (legend, annotations) and hover layers go on top
+    // lastly upper shapes, info (legend, annotations) and hover layers go on top
     // these are in a different svg element normally, but get collapsed into a single
     // svg when exporting (after inserting 3D)
+    // upper shapes/images are only those drawn above the whole plot, including subplots
+    var layerAbove = fullLayout._toppaper.append('g')
+        .classed('layer-above', true);
+    fullLayout._imageUpperLayer = layerAbove.append('g')
+        .classed('imagelayer', true);
+    fullLayout._shapeUpperLayer = layerAbove.append('g')
+        .classed('shapelayer', true);
+
     fullLayout._infolayer = fullLayout._toppaper.append('g').classed('infolayer', true);
+    fullLayout._menulayer = fullLayout._toppaper.append('g').classed('menulayer', true);
     fullLayout._zoomlayer = fullLayout._toppaper.append('g').classed('zoomlayer', true);
     fullLayout._hoverlayer = fullLayout._toppaper.append('g').classed('hoverlayer', true);
 
diff --git a/test/image/baselines/pie_style.png b/test/image/baselines/pie_style.png
index a0ff83a138a..14a7aca811d 100644
Binary files a/test/image/baselines/pie_style.png and b/test/image/baselines/pie_style.png differ
diff --git a/test/image/baselines/updatemenus.png b/test/image/baselines/updatemenus.png
index 616f19ebe79..4cd63cf3296 100644
Binary files a/test/image/baselines/updatemenus.png and b/test/image/baselines/updatemenus.png differ
diff --git a/test/image/mocks/pie_style.json b/test/image/mocks/pie_style.json
index d27a8b61f4b..e88a658322f 100644
--- a/test/image/mocks/pie_style.json
+++ b/test/image/mocks/pie_style.json
@@ -30,6 +30,29 @@
     "height": 400,
     "width": 500,
     "paper_bgcolor": "#ddd",
-    "showlegend": false
+    "showlegend": false,
+    "shapes": [{
+        "type": "rect",
+        "xref": "paper",
+        "yref": "paper",
+        "x0": 0,
+        "y0": 0.4,
+        "x1": 1,
+        "y1": 0.6,
+        "fillcolor": "rgba(128, 0, 0, 0.5)",
+        "line": {"width": 0},
+        "layer": "below"
+    }, {
+        "type": "rect",
+        "xref": "paper",
+        "yref": "paper",
+        "x0": 0.4,
+        "y0": 0,
+        "x1": 0.6,
+        "y1": 1,
+        "fillcolor": "rgba(0, 0, 128, 0.5)",
+        "line": {"width": 0},
+        "layer": "above"
+    }]
   }
 }
diff --git a/test/image/mocks/updatemenus.json b/test/image/mocks/updatemenus.json
index 32cd7e55e7d..7cfb9ca9ed9 100644
--- a/test/image/mocks/updatemenus.json
+++ b/test/image/mocks/updatemenus.json
@@ -79,6 +79,16 @@
       },
       "visible": false,
       "name": "Data set 3"
+    },
+    {
+        "x": [2, 3, 4],
+        "y": [0.4, 0.6, 0.8],
+        "z": [[1, 2], [3, 4]],
+        "type": "heatmap",
+        "colorbar": {
+            "x": -0.2,
+            "y": 0.6
+        }
     }
   ],
   "layout": {
@@ -123,7 +133,8 @@
                 true,
                 false,
                 false,
-                false
+                false,
+                true
               ]
             ],
             "label": "Data set 0"
@@ -136,7 +147,8 @@
                 false,
                 true,
                 false,
-                false
+                false,
+                true
               ]
             ],
             "label": "Data set 1"
@@ -149,7 +161,8 @@
                 false,
                 false,
                 true,
-                false
+                false,
+                true
               ]
             ],
             "label": "Data set 2"
@@ -162,6 +175,7 @@
                 false,
                 false,
                 false,
+                true,
                 true
               ]
             ],
diff --git a/test/jasmine/tests/updatemenus_test.js b/test/jasmine/tests/updatemenus_test.js
index 523a2d6f5e4..4e90579475d 100644
--- a/test/jasmine/tests/updatemenus_test.js
+++ b/test/jasmine/tests/updatemenus_test.js
@@ -671,6 +671,10 @@ describe('update menus interactions', function() {
             // fold up buttons whenever new menus are added
             assertMenus([0, 0]);
 
+            // dropdown buttons container should still be on top of headers (and non-dropdown buttons)
+            var gButton = d3.select('.updatemenu-dropdown-button-group');
+            expect(gButton.node().nextSibling).toBe(null);
+
             return Plotly.relayout(gd, {
                 'updatemenus[0].bgcolor': null,
                 'paper_bgcolor': 'black'
@@ -826,7 +830,7 @@ describe('update menus interaction with other components:', function() {
 
     afterEach(destroyGraphDiv);
 
-    it('buttons show be drawn above sliders', function(done) {
+    it('draws buttons above sliders', function(done) {
 
         Plotly.plot(createGraphDiv(), [{
             x: [1, 2, 3],
@@ -869,19 +873,12 @@ describe('update menus interaction with other components:', function() {
         })
         .then(function() {
             var infoLayer = d3.select('g.infolayer');
-            var containerClassNames = ['slider-container', 'updatemenu-container'];
-            var list = [];
-
-            infoLayer.selectAll('*').each(function() {
-                var className = d3.select(this).attr('class');
-
-                if(containerClassNames.indexOf(className) !== -1) {
-                    list.push(className);
-                }
-            });
-
-            expect(list).toEqual(containerClassNames);
+            var menuLayer = d3.select('g.menulayer');
+            expect(infoLayer.selectAll('.slider-container').size()).toBe(1);
+            expect(menuLayer.selectAll('.updatemenu-container').size()).toBe(1);
+            expect(infoLayer.node().nextSibling).toBe(menuLayer.node());
         })
+        .catch(fail)
         .then(done);
     });
 });