diff --git a/src/components/fx/hover.js b/src/components/fx/hover.js
index b8a57e5ee32..05a17c9c17e 100644
--- a/src/components/fx/hover.js
+++ b/src/components/fx/hover.js
@@ -194,8 +194,8 @@ exports.loneHover = function loneHover(hoverItems, opts) {
             d.offset -= anchor;
         });
 
-    var scaleX = opts.gd._fullLayout._inverseScaleX;
-    var scaleY = opts.gd._fullLayout._inverseScaleY;
+    var scaleX = opts.gd._fullLayout._invScaleX;
+    var scaleY = opts.gd._fullLayout._invScaleY;
     alignHoverText(hoverLabel, fullOpts.rotateLabels, scaleX, scaleY);
 
     return multiHover ? hoverLabel : hoverLabel.node();
@@ -340,7 +340,8 @@ function _hover(gd, evt, subplot, noHoverEvent) {
             xpx = evt.clientX - dbb.left;
             ypx = evt.clientY - dbb.top;
 
-            var transformedCoords = Lib.apply3DTransform(fullLayout._inverseTransform)(xpx, ypx);
+            fullLayout._calcInverseTransform(gd);
+            var transformedCoords = Lib.apply3DTransform(fullLayout._invTransform)(xpx, ypx);
 
             xpx = transformedCoords[0];
             ypx = transformedCoords[1];
@@ -725,7 +726,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
 
     if(!helpers.isUnifiedHover(hovermode)) {
         hoverAvoidOverlaps(hoverLabels, rotateLabels ? 'xa' : 'ya', fullLayout);
-        alignHoverText(hoverLabels, rotateLabels, fullLayout._inverseScaleX, fullLayout._inverseScaleY);
+        alignHoverText(hoverLabels, rotateLabels, fullLayout._invScaleX, fullLayout._invScaleY);
     }    // TODO: tagName hack is needed to appease geo.js's hack of using evt.target=true
     // we should improve the "fx" API so other plots can use it without these hack.
     if(evt.target && evt.target.tagName) {
diff --git a/src/lib/dom.js b/src/lib/dom.js
index cd2a0ec6690..99154835919 100644
--- a/src/lib/dom.js
+++ b/src/lib/dom.js
@@ -150,6 +150,18 @@ function isTransformableElement(element) {
     return element && (element instanceof Element || element instanceof HTMLElement);
 }
 
+function equalDomRects(a, b) {
+    return (
+        a && b &&
+        a.x === b.x &&
+        a.y === b.y &&
+        a.top === b.top &&
+        a.left === b.left &&
+        a.right === b.right &&
+        a.bottom === b.bottom
+    );
+}
+
 module.exports = {
     getGraphDiv: getGraphDiv,
     isPlotDiv: isPlotDiv,
@@ -160,4 +172,5 @@ module.exports = {
     getFullTransformMatrix: getFullTransformMatrix,
     getElementTransformMatrix: getElementTransformMatrix,
     getElementAndAncestors: getElementAndAncestors,
+    equalDomRects: equalDomRects
 };
diff --git a/src/lib/index.js b/src/lib/index.js
index 95904592cd7..da28ce654a1 100644
--- a/src/lib/index.js
+++ b/src/lib/index.js
@@ -151,6 +151,7 @@ lib.deleteRelatedStyleRule = domModule.deleteRelatedStyleRule;
 lib.getFullTransformMatrix = domModule.getFullTransformMatrix;
 lib.getElementTransformMatrix = domModule.getElementTransformMatrix;
 lib.getElementAndAncestors = domModule.getElementAndAncestors;
+lib.equalDomRects = domModule.equalDomRects;
 
 lib.clearResponsive = require('./clear_responsive');
 
diff --git a/src/lib/svg_text_utils.js b/src/lib/svg_text_utils.js
index 7b49ed7da04..e9549eab98f 100644
--- a/src/lib/svg_text_utils.js
+++ b/src/lib/svg_text_utils.js
@@ -748,9 +748,12 @@ function alignHTMLWith(_base, container, options) {
         var x0 = getLeft() - cRect.left;
         var y0 = getTop() - cRect.top;
         var gd = options.gd || {};
-        var transformedCoords = Lib.apply3DTransform(gd._fullLayout._inverseTransform)(x0, y0);
-        x0 = transformedCoords[0];
-        y0 = transformedCoords[1];
+        if(options.gd) {
+            gd._fullLayout._calcInverseTransform(gd);
+            var transformedCoords = Lib.apply3DTransform(gd._fullLayout._invTransform)(x0, y0);
+            x0 = transformedCoords[0];
+            y0 = transformedCoords[1];
+        }
 
         this.style({
             top: y0 + 'px',
diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js
index e43c0daf850..6c88d1b4022 100644
--- a/src/plot_api/plot_api.js
+++ b/src/plot_api/plot_api.js
@@ -3706,17 +3706,28 @@ function purge(gd) {
     return gd;
 }
 
+// determines if the graph div requires a recalculation of its inverse matrix transforms by comparing old + new bounding boxes.
+function calcInverseTransform(gd) {
+    var fullLayout = gd._fullLayout;
+
+    var newBBox = gd.getBoundingClientRect();
+    if(Lib.equalDomRects(newBBox, fullLayout._lastBBox)) return;
+
+    var m = fullLayout._invTransform = Lib.inverseTransformMatrix(Lib.getFullTransformMatrix(gd));
+    fullLayout._invScaleX = Math.sqrt(m[0][0] * m[0][0] + m[0][1] * m[0][1] + m[0][2] * m[0][2]);
+    fullLayout._invScaleY = Math.sqrt(m[1][0] * m[1][0] + m[1][1] * m[1][1] + m[1][2] * m[1][2]);
+    fullLayout._lastBBox = newBBox;
+}
+
 // -------------------------------------------------------
 // makePlotFramework: Create the plot container and axes
 // -------------------------------------------------------
 function makePlotFramework(gd) {
     var gd3 = d3.select(gd);
     var fullLayout = gd._fullLayout;
-    if(fullLayout._inverseTransform === undefined) {
-        var m = fullLayout._inverseTransform = Lib.inverseTransformMatrix(Lib.getFullTransformMatrix(gd));
-        fullLayout._inverseScaleX = Math.sqrt(m[0][0] * m[0][0] + m[0][1] * m[0][1] + m[0][2] * m[0][2]);
-        fullLayout._inverseScaleY = Math.sqrt(m[1][0] * m[1][0] + m[1][1] * m[1][1] + m[1][2] * m[1][2]);
-    }
+
+    fullLayout._calcInverseTransform = calcInverseTransform;
+    fullLayout._calcInverseTransform(gd);
 
     // Plot container
     fullLayout._container = gd3.selectAll('.plot-container').data([0]);
diff --git a/src/plots/cartesian/dragbox.js b/src/plots/cartesian/dragbox.js
index e27c98c6063..e4128972f4c 100644
--- a/src/plots/cartesian/dragbox.js
+++ b/src/plots/cartesian/dragbox.js
@@ -166,8 +166,8 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
 
         recomputeAxisLists();
 
-        scaleX = gd._fullLayout._inverseScaleX;
-        scaleY = gd._fullLayout._inverseScaleY;
+        scaleX = gd._fullLayout._invScaleX;
+        scaleY = gd._fullLayout._invScaleY;
 
         if(!allFixedRanges) {
             if(isMainDrag) {
@@ -335,7 +335,8 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
         x0 = startX - dragBBox.left;
         y0 = startY - dragBBox.top;
 
-        var transformedCoords = Lib.apply3DTransform(gd._fullLayout._inverseTransform)(x0, y0);
+        gd._fullLayout._calcInverseTransform(gd);
+        var transformedCoords = Lib.apply3DTransform(gd._fullLayout._invTransform)(x0, y0);
         x0 = transformedCoords[0];
         y0 = transformedCoords[1];
 
diff --git a/src/plots/cartesian/select.js b/src/plots/cartesian/select.js
index 029f32815e6..72156ea80f5 100644
--- a/src/plots/cartesian/select.js
+++ b/src/plots/cartesian/select.js
@@ -68,11 +68,12 @@ function prepSelect(e, startX, startY, dragOptions, mode) {
     var x0 = startX - dragBBox.left;
     var y0 = startY - dragBBox.top;
 
-    var transformedCoords = Lib.apply3DTransform(fullLayout._inverseTransform)(x0, y0);
+    fullLayout._calcInverseTransform(gd);
+    var transformedCoords = Lib.apply3DTransform(fullLayout._invTransform)(x0, y0);
     x0 = transformedCoords[0];
     y0 = transformedCoords[1];
-    var scaleX = fullLayout._inverseScaleX;
-    var scaleY = fullLayout._inverseScaleY;
+    var scaleX = fullLayout._invScaleX;
+    var scaleY = fullLayout._invScaleY;
 
     var x1 = x0;
     var y1 = y0;
diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js
index d85578bb2d3..a522afa8fcd 100644
--- a/src/plots/gl3d/scene.js
+++ b/src/plots/gl3d/scene.js
@@ -307,8 +307,10 @@ proto.render = function() {
     // update size of svg container
     var svgContainer = scene.svgContainer;
     var clientRect = scene.container.getBoundingClientRect();
-    var scaleX = gd._fullLayout._inverseScaleX;
-    var scaleY = gd._fullLayout._inverseScaleY;
+
+    gd._fullLayout._calcInverseTransform(gd);
+    var scaleX = gd._fullLayout._invScaleX;
+    var scaleY = gd._fullLayout._invScaleY;
     var width = clientRect.width * scaleX;
     var height = clientRect.height * scaleY;
     svgContainer.setAttributeNS(null, 'viewBox', '0 0 ' + width + ' ' + height);
diff --git a/src/plots/polar/polar.js b/src/plots/polar/polar.js
index 6bc95814e5f..57a4ac167d9 100644
--- a/src/plots/polar/polar.js
+++ b/src/plots/polar/polar.js
@@ -680,8 +680,8 @@ proto.updateMainDrag = function(fullLayout) {
     var chw = constants.cornerHalfWidth;
     var chl = constants.cornerLen / 2;
 
-    var scaleX = gd._fullLayout._inverseScaleX;
-    var scaleY = gd._fullLayout._inverseScaleY;
+    var scaleX;
+    var scaleY;
 
     var mainDrag = dragBox.makeDragger(layers, 'path', 'maindrag', 'crosshair');
 
@@ -943,7 +943,10 @@ proto.updateMainDrag = function(fullLayout) {
         var dragModeNow = gd._fullLayout.dragmode;
 
         var bbox = mainDrag.getBoundingClientRect();
-        var inverse = gd._fullLayout._inverseTransform;
+        gd._fullLayout._calcInverseTransform(gd);
+        var inverse = gd._fullLayout._invTransform;
+        scaleX = gd._fullLayout._invScaleX;
+        scaleY = gd._fullLayout._invScaleY;
         var transformedCoords = Lib.apply3DTransform(inverse)(startX - bbox.left, startY - bbox.top);
         x0 = transformedCoords[0];
         y0 = transformedCoords[1];
@@ -1198,8 +1201,8 @@ proto.updateAngularDrag = function(fullLayout) {
         var fullLayoutNow = _this.gd._fullLayout;
         var polarLayoutNow = fullLayoutNow[_this.id];
 
-        var x1 = x0 + dx * fullLayout._inverseScaleX;
-        var y1 = y0 + dy * fullLayout._inverseScaleY;
+        var x1 = x0 + dx * fullLayout._invScaleX;
+        var y1 = y0 + dy * fullLayout._invScaleY;
         var a1 = xy2a(x1, y1);
         var da = rad2deg(a1 - a0);
         rot1 = rot0 + da;
@@ -1293,7 +1296,8 @@ proto.updateAngularDrag = function(fullLayout) {
         x0 = startX - bbox.left;
         y0 = startY - bbox.top;
 
-        var transformedCoords = Lib.apply3DTransform(fullLayout._inverseTransform)(x0, y0);
+        gd._fullLayout._calcInverseTransform(gd);
+        var transformedCoords = Lib.apply3DTransform(fullLayout._invTransform)(x0, y0);
         x0 = transformedCoords[0];
         y0 = transformedCoords[1];
 
diff --git a/src/plots/ternary/ternary.js b/src/plots/ternary/ternary.js
index 82d178ecd43..0918c5947a2 100644
--- a/src/plots/ternary/ternary.js
+++ b/src/plots/ternary/ternary.js
@@ -523,8 +523,8 @@ proto.initInteractions = function() {
             _this.dragOptions.xaxes = [_this.xaxis];
             _this.dragOptions.yaxes = [_this.yaxis];
 
-            scaleX = gd._fullLayout._inverseScaleX;
-            scaleY = gd._fullLayout._inverseScaleY;
+            scaleX = gd._fullLayout._invScaleX;
+            scaleY = gd._fullLayout._invScaleY;
 
             var dragModeNow = _this.dragOptions.dragmode = gd._fullLayout.dragmode;
 
@@ -579,9 +579,11 @@ proto.initInteractions = function() {
 
     function zoomPrep(e, startX, startY) {
         var dragBBox = dragger.getBoundingClientRect();
-        var inverse = gd._fullLayout._inverseTransform;
         x0 = startX - dragBBox.left;
         y0 = startY - dragBBox.top;
+
+        gd._fullLayout._calcInverseTransform(gd);
+        var inverse = gd._fullLayout._invTransform;
         var transformedCoords = Lib.apply3DTransform(inverse)(x0, y0);
         x0 = transformedCoords[0];
         y0 = transformedCoords[1];
diff --git a/src/traces/parcats/parcats.js b/src/traces/parcats/parcats.js
index b1a60567ab2..733fa32fa0f 100644
--- a/src/traces/parcats/parcats.js
+++ b/src/traces/parcats/parcats.js
@@ -767,8 +767,9 @@ function emitPointsEventColorHovermode(bandElement, eventName, event) {
  *
  */
 function createHoverLabelForCategoryHovermode(gd, rootBBox, bandElement) {
-    var scaleX = gd._fullLayout._inverseScaleX;
-    var scaleY = gd._fullLayout._inverseScaleY;
+    gd._fullLayout._calcInverseTransform(gd);
+    var scaleX = gd._fullLayout._invScaleX;
+    var scaleY = gd._fullLayout._invScaleY;
 
     // Selections
     var rectSelection = d3.select(bandElement.parentNode).select('rect.catrect');
@@ -871,8 +872,9 @@ function createHoverLabelForDimensionHovermode(gd, rootBBox, bandElement) {
  *
  */
 function createHoverLabelForColorHovermode(gd, rootBBox, bandElement) {
-    var scaleX = gd._fullLayout._inverseScaleX;
-    var scaleY = gd._fullLayout._inverseScaleY;
+    gd._fullLayout._calcInverseTransform(gd);
+    var scaleX = gd._fullLayout._invScaleX;
+    var scaleY = gd._fullLayout._invScaleY;
 
     var bandBoundingBox = bandElement.getBoundingClientRect();
 
diff --git a/src/traces/sankey/plot.js b/src/traces/sankey/plot.js
index 6356ff3fa4c..6d6abb157a6 100644
--- a/src/traces/sankey/plot.js
+++ b/src/traces/sankey/plot.js
@@ -292,8 +292,9 @@ module.exports = function plot(gd, calcData) {
         var hovertemplateLabels = {valueLabel: d3.format(d.valueFormat)(d.node.value) + d.valueSuffix};
         d.node.fullData = d.node.trace;
 
-        var scaleX = gd._fullLayout._inverseScaleX;
-        var scaleY = gd._fullLayout._inverseScaleY;
+        gd._fullLayout._calcInverseTransform(gd);
+        var scaleX = gd._fullLayout._invScaleX;
+        var scaleY = gd._fullLayout._invScaleY;
 
         var tooltip = Fx.loneHover({
             x0: scaleX * hoverCenterX0,
diff --git a/test/jasmine/tests/cartesian_interact_test.js b/test/jasmine/tests/cartesian_interact_test.js
index a351246fe22..e1a368f2ae8 100644
--- a/test/jasmine/tests/cartesian_interact_test.js
+++ b/test/jasmine/tests/cartesian_interact_test.js
@@ -2475,9 +2475,10 @@ describe('Cartesian plots with css transforms', function() {
                 });
             }
 
-            transformPlot(gd, transform);
             Plotly.newPlot(gd, Lib.extendDeep({}, mock))
             .then(function() {
+                transformPlot(gd, transform);
+
                 gd.on('plotly_hover', function(d) {
                     eventRecordings[d.points[0].x] = 1;
                 });
@@ -2505,8 +2506,8 @@ describe('Cartesian plots with css transforms', function() {
             // asserts that the zoombox path must go from the start to end positions,
             // in css-transformed coordinates.
             function _assertTransformedZoombox(startPos, endPos) {
-                startPos = Lib.apply3DTransform(gd._fullLayout._inverseTransform)(startPos[0], startPos[1]);
-                endPos = Lib.apply3DTransform(gd._fullLayout._inverseTransform)(endPos[0], endPos[1]);
+                startPos = Lib.apply3DTransform(gd._fullLayout._invTransform)(startPos[0], startPos[1]);
+                endPos = Lib.apply3DTransform(gd._fullLayout._invTransform)(endPos[0], endPos[1]);
                 var size = [endPos[0] - startPos[0], endPos[1] - startPos[1]];
                 var zb = d3.select(gd).select('g.zoomlayer > path.zoombox');
                 var zoomboxRect = _getZoomlayerPathRect(zb.attr('d'));
@@ -2519,9 +2520,12 @@ describe('Cartesian plots with css transforms', function() {
             var start = [50, 50];
             var end = [150, 150];
 
-            transformPlot(gd, transform);
             Plotly.newPlot(gd, Lib.extendDeep({}, mock))
-            .then(function() {_drag(start, end); })
+            .then(function() {
+                transformPlot(gd, transform);
+
+                _drag(start, end);
+            })
             .then(function() {
                 _assertTransformedZoombox(start, end);
             })
@@ -2547,9 +2551,10 @@ describe('Cartesian plots with css transforms', function() {
             var start = [10, 10];
             var end = [200, 200];
 
-            transformPlot(gd, transform);
             Plotly.newPlot(gd, Lib.extendDeep({}, mock))
             .then(function() {
+                transformPlot(gd, transform);
+
                 return Plotly.relayout(gd, 'dragmode', 'select');
             })
             .then(function() {
diff --git a/test/jasmine/tests/choropleth_test.js b/test/jasmine/tests/choropleth_test.js
index 9e8a6a173eb..8d263da441e 100644
--- a/test/jasmine/tests/choropleth_test.js
+++ b/test/jasmine/tests/choropleth_test.js
@@ -167,10 +167,6 @@ describe('Test choropleth hover:', function() {
     function run(hasCssTransform, pos, fig, content, style) {
         gd = createGraphDiv();
         var scale = 1;
-        if(hasCssTransform) {
-            scale = 0.5;
-            transformPlot(gd, 'translate(-25%, -25%) scale(0.5)');
-        }
 
         style = style || {
             bgcolor: 'rgb(68, 68, 68)',
@@ -180,7 +176,13 @@ describe('Test choropleth hover:', function() {
             fontFamily: 'Arial'
         };
 
-        return Plotly.plot(gd, fig).then(function() {
+        return Plotly.plot(gd, fig)
+        .then(function() {
+            if(hasCssTransform) {
+                scale = 0.5;
+                transformPlot(gd, 'translate(-25%, -25%) scale(0.5)');
+            }
+
             mouseEvent('mousemove', scale * pos[0], scale * pos[1]);
             assertHoverLabelContent({
                 nums: content[0],
diff --git a/test/jasmine/tests/choroplethmapbox_test.js b/test/jasmine/tests/choroplethmapbox_test.js
index 7e5fd3aaa3b..e01641bd5f1 100644
--- a/test/jasmine/tests/choroplethmapbox_test.js
+++ b/test/jasmine/tests/choroplethmapbox_test.js
@@ -538,7 +538,6 @@ describe('@noCI Test choroplethmapbox hover:', function() {
         var scale = 1;
         if(hasCssTransform) {
             scale = 0.5;
-            transformPlot(gd, 'translate(-25%, -25%) scale(0.5)');
         }
 
         var fig = Lib.extendDeep({},
@@ -556,6 +555,8 @@ describe('@noCI Test choroplethmapbox hover:', function() {
         var pos = s.pos || [270, 220];
 
         return Plotly.plot(gd, fig).then(function() {
+            if(hasCssTransform) transformPlot(gd, 'translate(-25%, -25%) scale(0.5)');
+
             var to = setTimeout(function() {
                 failTest('no event data received');
                 done();
diff --git a/test/jasmine/tests/polar_test.js b/test/jasmine/tests/polar_test.js
index eb57674905b..4278881e027 100644
--- a/test/jasmine/tests/polar_test.js
+++ b/test/jasmine/tests/polar_test.js
@@ -1746,9 +1746,10 @@ describe('Polar plots with css transforms', function() {
         it('hover behaves correctly after css transform: ' + transform, function(done) {
             var hoverEvents = {};
 
-            transformPlot(gd, transform);
             Plotly.newPlot(gd, Lib.extendDeep({}, mock))
             .then(function() {
+                transformPlot(gd, transform);
+
                 gd.on('plotly_hover', function(d) {
                     hoverEvents[d.points[0].pointIndex] = true;
                 });
@@ -1765,10 +1766,11 @@ describe('Polar plots with css transforms', function() {
         });
 
         it('drag-zoom behaves correctly after css transform: ' + transform, function(done) {
-            transformPlot(gd, transform);
             Plotly.newPlot(gd, Lib.extendDeep({}, mock))
 
             .then(function() {
+                transformPlot(gd, transform);
+
                 return _drag([10, 10], [50, 50]);
             })
             .then(function() {
@@ -1789,9 +1791,10 @@ describe('Polar plots with css transforms', function() {
                 }
             }
 
-            transformPlot(gd, transform);
             Plotly.newPlot(gd, Lib.extendDeep({}, mock))
             .then(function() {
+                transformPlot(gd, transform);
+
                 return Plotly.relayout(gd, 'dragmode', 'select');
             })
             .then(function() { return _drag([30, 30], [130, 130]); })
diff --git a/test/jasmine/tests/scattermapbox_test.js b/test/jasmine/tests/scattermapbox_test.js
index 63d3df59230..e788b341e2f 100644
--- a/test/jasmine/tests/scattermapbox_test.js
+++ b/test/jasmine/tests/scattermapbox_test.js
@@ -1099,8 +1099,9 @@ describe('@noCI Test plotly events on a scattermapbox plot when css transform is
         mockCopy.layout.width = 800;
         mockCopy.layout.height = 500;
 
-        transformPlot(gd, 'translate(-25%, -25%) scale(0.5)');
-        Plotly.plot(gd, mockCopy).then(done);
+        Plotly.plot(gd, mockCopy)
+            .then(function() { transformPlot(gd, 'translate(-25%, -25%) scale(0.5)'); })
+            .then(done);
     });
 
     afterEach(destroyGraphDiv);
diff --git a/test/jasmine/tests/select_test.js b/test/jasmine/tests/select_test.js
index f5a1cee024a..e032731ab21 100644
--- a/test/jasmine/tests/select_test.js
+++ b/test/jasmine/tests/select_test.js
@@ -1894,8 +1894,10 @@ describe('Test select box and lasso per trace:', function() {
             fig.layout.dragmode = 'select';
             addInvisible(fig);
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
-            Plotly.plot(gd, fig).then(function() {
+            Plotly.plot(gd, fig)
+            .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[400, 200], [445, 235]],
                     function() {
@@ -1950,8 +1952,10 @@ describe('Test select box and lasso per trace:', function() {
             fig.layout.dragmode = 'select';
             addInvisible(fig);
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
-            Plotly.plot(gd, fig).then(function() {
+            Plotly.plot(gd, fig)
+            .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[300, 200], [400, 250]],
                     function() {
@@ -1997,8 +2001,10 @@ describe('Test select box and lasso per trace:', function() {
             };
             addInvisible(fig);
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
-            Plotly.plot(gd, fig).then(function() {
+            Plotly.plot(gd, fig)
+            .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[370, 120], [500, 200]],
                     function() {
@@ -2056,8 +2062,10 @@ describe('Test select box and lasso per trace:', function() {
             };
             addInvisible(fig);
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
-            Plotly.plot(gd, fig).then(function() {
+            Plotly.plot(gd, fig)
+            .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[150, 150], [300, 300]],
                     function() {
@@ -2128,9 +2136,10 @@ describe('Test select box and lasso per trace:', function() {
             };
             addInvisible(fig);
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
             Plotly.plot(gd, fig)
             .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[350, 200], [450, 400]],
                     function() {
@@ -2202,8 +2211,10 @@ describe('Test select box and lasso per trace:', function() {
             fig.layout.dragmode = 'select';
             addInvisible(fig);
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
-            Plotly.plot(gd, fig).then(function() {
+            Plotly.plot(gd, fig)
+            .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[150, 150], [350, 250]],
                     function() {
@@ -2245,8 +2256,10 @@ describe('Test select box and lasso per trace:', function() {
             fig.layout.dragmode = 'select';
             addInvisible(fig);
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
-            Plotly.plot(gd, fig).then(function() {
+            Plotly.plot(gd, fig)
+            .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[150, 150], [250, 250]],
                     function() {
@@ -2313,9 +2326,10 @@ describe('Test select box and lasso per trace:', function() {
             emptyChoroplethTrace.z = [];
             fig.data.push(emptyChoroplethTrace);
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
             Plotly.plot(gd, fig)
             .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[350, 200], [400, 250]],
                     function() {
@@ -2369,9 +2383,10 @@ describe('Test select box and lasso per trace:', function() {
             fig.layout.dragmode = 'lasso';
             addInvisible(fig);
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
             Plotly.plot(gd, fig)
             .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[400, 300], [200, 400], [400, 500], [600, 400], [500, 350]],
                     function() {
@@ -2430,9 +2445,10 @@ describe('Test select box and lasso per trace:', function() {
             fig.layout.dragmode = 'lasso';
             addInvisible(fig);
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
             Plotly.plot(gd, fig)
             .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[400, 300], [200, 400], [400, 500], [600, 400], [500, 350]],
                     function() {
@@ -2493,9 +2509,10 @@ describe('Test select box and lasso per trace:', function() {
             fig.layout.dragmode = 'lasso';
             addInvisible(fig);
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
             Plotly.plot(gd, fig)
             .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[350, 200], [400, 200], [400, 250], [350, 250], [350, 200]],
                     function() {
@@ -2600,9 +2617,10 @@ describe('Test select box and lasso per trace:', function() {
             var x1 = 250;
             var y1 = 250;
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
             Plotly.plot(gd, fig)
             .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[x0, y0], [x1, y0], [x1, y1], [x0, y1], [x0, y0]],
                     function() {
@@ -2649,9 +2667,10 @@ describe('Test select box and lasso per trace:', function() {
             fig.layout.height = 500;
             addInvisible(fig);
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
             Plotly.plot(gd, fig)
             .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[200, 200], [400, 200], [400, 350], [200, 350], [200, 200]],
                     function() {
@@ -2705,9 +2724,10 @@ describe('Test select box and lasso per trace:', function() {
             fig.layout.xaxis = {range: [-0.565, 1.5]};
             addInvisible(fig);
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
             Plotly.plot(gd, fig)
             .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[200, 200], [400, 200], [400, 350], [200, 350], [200, 200]],
                     function() {
@@ -2778,9 +2798,10 @@ describe('Test select box and lasso per trace:', function() {
                 }
             };
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
             Plotly.plot(gd, fig)
             .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[200, 200], [400, 200], [400, 350], [200, 350], [200, 200]],
                     function() {
@@ -2821,9 +2842,10 @@ describe('Test select box and lasso per trace:', function() {
             fig.layout.height = 500;
             addInvisible(fig);
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
             Plotly.plot(gd, fig)
             .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[200, 200], [400, 200], [400, 350], [200, 350], [200, 200]],
                     function() {
@@ -2903,7 +2925,6 @@ describe('Test select box and lasso per trace:', function() {
                     return unselected;
                 }
 
-                if(hasCssTransform) transformPlot(gd, cssTransform);
                 Plotly.newPlot(gd, [{
                     type: type,
                     x: ['2011-01-02', '2011-01-03', '2011-01-04'],
@@ -2919,6 +2940,8 @@ describe('Test select box and lasso per trace:', function() {
                     dragmode: 'lasso'
                 })
                 .then(function() {
+                    if(hasCssTransform) transformPlot(gd, cssTransform);
+
                     return _run(hasCssTransform,
                         [[l0, t], [l0, b], [r0, b], [r0, t], [l0, t]],
                         function() {
@@ -2958,7 +2981,6 @@ describe('Test select box and lasso per trace:', function() {
         it('@flaky should work on traces with enabled transforms, hasCssTransform: ' + hasCssTransform, function(done) {
             var assertSelectedPoints = makeAssertSelectedPoints();
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
             Plotly.plot(gd, [{
                 x: [1, 2, 3, 4, 5],
                 y: [2, 3, 1, 7, 9],
@@ -2986,6 +3008,8 @@ describe('Test select box and lasso per trace:', function() {
                 margin: {l: 0, t: 0, r: 0, b: 0}
             })
             .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[5, 5], [395, 395]],
                     function() {
@@ -3015,7 +3039,6 @@ describe('Test select box and lasso per trace:', function() {
                 });
             }
 
-            if(hasCssTransform) transformPlot(gd, cssTransform);
             Plotly.plot(gd, [{
                 mode: 'markers+text',
                 x: [1, 2, 3],
@@ -3036,6 +3059,8 @@ describe('Test select box and lasso per trace:', function() {
                 margin: {l: 0, t: 0, r: 0, b: 0}
             })
             .then(function() {
+                if(hasCssTransform) transformPlot(gd, cssTransform);
+
                 return _run(hasCssTransform,
                     [[10, 10], [100, 300]],
                     function() {
@@ -3062,9 +3087,10 @@ describe('Test select box and lasso per trace:', function() {
                 fig.layout.dragmode = 'select';
                 var dblClickPos = [250, 400];
 
-                if(hasCssTransform) transformPlot(gd, cssTransform);
                 Plotly.plot(gd, fig)
                 .then(function() {
+                    if(hasCssTransform) transformPlot(gd, cssTransform);
+
                     // No groups initially
                     expect(gd._fullData[0].node.groups).toEqual([]);
                 })
diff --git a/test/jasmine/tests/ternary_test.js b/test/jasmine/tests/ternary_test.js
index cdc3b95c559..624f362eec1 100644
--- a/test/jasmine/tests/ternary_test.js
+++ b/test/jasmine/tests/ternary_test.js
@@ -585,8 +585,9 @@ describe('ternary plots when css transform is present', function() {
 
         var mockCopy = Lib.extendDeep({}, mock);
 
-        transformPlot(gd, cssTransform);
-        Plotly.plot(gd, mockCopy.data, mockCopy.layout).then(done);
+        Plotly.plot(gd, mockCopy.data, mockCopy.layout)
+            .then(function() { transformPlot(gd, cssTransform); })
+            .then(done);
     });
 
     it('should respond zoom drag interactions', function(done) {