diff --git a/plotly/plotly_aux/Test_m2json.m b/plotly/plotly_aux/Test_m2json.m
new file mode 100644
index 00000000..8cb2d0d2
--- /dev/null
+++ b/plotly/plotly_aux/Test_m2json.m
@@ -0,0 +1,58 @@
+classdef Test_m2json < matlab.unittest.TestCase
+    methods (Test)
+        function testInRange0to10(tc)
+            values = 1 + (1:5) + 0.23456789;
+            expected = "[2.235,3.235,4.235,5.235,6.235]";
+            tc.verifyEqual(string(m2json(values)), expected);
+        end
+
+        function test2dArrayInRange0to10(tc)
+            values = 1 + (1:5) + (0:1)' + 0.23456789;
+            expected = "[[2.235,3.235,4.235,5.235,6.235]," ...
+                    + "[3.235,4.235,5.235,6.235,7.235]]";
+            tc.verifyEqual(string(m2json(values)), expected);
+        end
+
+        function testInRange1e6to1e5(tc)
+            values = 1e-6 * (1 + (1:5) + 0.23456789);
+            expected = "[2.235e-06,3.235e-06,4.235e-06,5.235e-06,6.235e-06]";
+            tc.verifyEqual(string(m2json(values)), expected);
+        end
+
+        function testInRange1e14Plus0to1(tc)
+            values = 1e14 + (1:5) + 0.23456789;
+            expected = "[100000000000001,100000000000002,100000000000003,100000000000004,100000000000005]";
+            tc.verifyEqual(string(m2json(values)), expected);
+        end
+
+        function testInRange1e14Plus1e7Plus0to1(tc)
+            values = 1e14 + 1e7 + (1:5) + 0.23456789;
+            expected = "[100000010000001,100000010000002,100000010000003,100000010000004,100000010000005]";
+            tc.verifyEqual(string(m2json(values)), expected);
+        end
+
+        function testLogScaledVariables(tc)
+            values = 1e14 + 10.^(1:5) + 0.23456789;
+            expected = "[1e+14,1.000000000001e+14,1.00000000001e+14,1.0000000001e+14,1.000000001e+14]";
+            tc.verifyEqual(string(m2json(values)), expected);
+        end
+
+        function testInRangeMinus10to0(tc)
+            values = -(1 + (1:5) + 0.23456789);
+            expected = "[-2.235,-3.235,-4.235,-5.235,-6.235]";
+            tc.verifyEqual(string(m2json(values)), expected);
+        end
+
+        function testInRangeMinus1e5toMinus1e6(tc)
+            values = -1e-6 * (1 + (1:5) + 0.23456789);
+            expected = "[-2.235e-06,-3.235e-06,-4.235e-06,-5.235e-06,-6.235e-06]";
+            tc.verifyEqual(string(m2json(values)), expected);
+        end
+
+        function testInRangeMinus1e14Plus0to1(tc)
+            values = -1e14 + (1:5) + 0.23456789;
+            expected = "[-99999999999998.8,-99999999999997.8,-99999999999996.8,-99999999999995.8,-99999999999994.8]";
+            tc.verifyEqual(string(m2json(values)), expected);
+        end
+    end
+end
diff --git a/plotly/plotly_aux/m2json.m b/plotly/plotly_aux/m2json.m
index d17eb2e1..f9f9b309 100644
--- a/plotly/plotly_aux/m2json.m
+++ b/plotly/plotly_aux/m2json.m
@@ -5,29 +5,23 @@
         valstr = cell2json(val);
     elseif isa(val, "numeric")
         sz = size(val);
-        if isa(val,"single")
-            precision = "7";
-        else
-            precision = "15";
-        end
-        fmt = "%." + precision + "g,";
-        if length(find(sz>1))>1 % 2D or higher array
-            valstr = "";
+        numDigits = 3 + ceil(clip(log10(double(max(abs(val),[],"all"))) ...
+                - log10(double(range(val,"all"))),0,12));
+        numDigits(~isfinite(numDigits)) = 7;
+        fmt = sprintf("%%.%ig", numDigits);
+        if sum(sz>1)>1 % 2D or higher array
+            valsubstr = strings(1, sz(1));
             for i = 1:sz(1)
-                valsubstr = sprintf(fmt, val(i,:));
-                valsubstr = valsubstr(1:(end-1));
-                valstr = valstr + ", [" + valsubstr + "]";
+                formattedRowVal = arrayfun(@(x) sprintf(fmt, x), val(i,:));
+                valsubstr(i) = strjoin(formattedRowVal, ",");
+                valsubstr(i) = "[" + valsubstr(i) + "]";
             end
-            valstr = valstr(3:end); % trail leading commas
+            valstr = strjoin(valsubstr, ",");
         else
-            valstr = [sprintf(fmt, val)];
-            valstr = valstr(1:(end-1));
-        end
-        if length(val)>1
-            valstr = "[" + valstr + "]";
-        elseif isempty(val)
-            valstr = "[]";
+            valstr = arrayfun(@(x) sprintf(fmt, x), val);
+            valstr = strjoin(valstr, ",");
         end
+        valstr = "[" + valstr + "]";
         valstr = strrep(valstr,"-Inf", "null");
         valstr = strrep(valstr, "Inf", "null");
         valstr = strrep(valstr, "NaN", "null");
@@ -60,3 +54,8 @@
         warning("Failed to m2json encode class of type: %s", class(val));
     end
 end
+
+function x = clip(x,lb,ub)
+    x(x<lb) = lb;
+    x(x>ub) = ub;
+end
