diff --git a/frontend/src/metabase/visualizations/components/ChoroplethMap.jsx b/frontend/src/metabase/visualizations/components/ChoroplethMap.jsx
index ad01d3562b3b3f55fe5a61474678f270309a7721..2d4148ae35b259e001f92b5662c4b14ec97013d2 100644
--- a/frontend/src/metabase/visualizations/components/ChoroplethMap.jsx
+++ b/frontend/src/metabase/visualizations/components/ChoroplethMap.jsx
@@ -69,6 +69,36 @@ function loadGeoJson(geoJsonPath, callback) {
   }
 }
 
+export function getLegendTitles(groups, columnSettings) {
+  const formatMetric = (value, compact) =>
+    formatValue(value, { ...columnSettings, compact });
+
+  const compact = shouldUseCompactFormatting(groups, formatMetric);
+
+  return groups.map((group, index) => {
+    const min = formatMetric(group[0], compact);
+    const max = formatMetric(group[group.length - 1], compact);
+    return index === groups.length - 1
+      ? `${min} +` // the last value in the list
+      : min !== max
+      ? `${min} - ${max}` // typical case
+      : min; // special case to avoid zero-width ranges e.g. $88-$88
+  });
+}
+
+// if the average formatted length is greater than this, we switch to compact formatting
+const AVERAGE_LENGTH_CUTOFF = 5;
+function shouldUseCompactFormatting(groups, formatMetric) {
+  const minValues = groups.map(([x]) => x);
+  const maxValues = groups.slice(0, -1).map(group => group[group.length - 1]);
+  const allValues = minValues.concat(maxValues);
+  const formattedValues = allValues.map(value => formatMetric(value, false));
+  const averageLength =
+    formattedValues.reduce((sum, { length }) => sum + length, 0) /
+    formattedValues.length;
+  return averageLength > AVERAGE_LENGTH_CUTOFF;
+}
+
 export default class ChoroplethMap extends Component {
   static propTypes = {};
 
@@ -197,9 +227,6 @@ export default class ChoroplethMap extends Component {
 
     const getFeatureValue = feature => valuesMap[getFeatureKey(feature)];
 
-    const formatMetric = value =>
-      formatValue(value, settings.column(cols[metricIndex]));
-
     const rowByFeatureKey = new Map(rows.map(row => [getRowKey(row), row]));
 
     const getFeatureClickObject = (row, feature) => ({
@@ -253,10 +280,7 @@ export default class ChoroplethMap extends Component {
     const domain = Array.from(domainSet);
 
     const _heatMapColors = settings["map.colors"] || HEAT_MAP_COLORS;
-    const heatMapColors =
-      domain.length < _heatMapColors.length
-        ? _heatMapColors.slice(_heatMapColors.length - domain.length)
-        : _heatMapColors;
+    const heatMapColors = _heatMapColors.slice(-domain.length);
 
     const groups = ss.ckmeans(domain, heatMapColors.length);
     const groupBoundaries = groups.slice(1).map(cluster => cluster[0]);
@@ -266,14 +290,8 @@ export default class ChoroplethMap extends Component {
       .domain(groupBoundaries)
       .range(heatMapColors);
 
-    const legendColors = heatMapColors;
-    const legendTitles = heatMapColors.map((color, index) => {
-      const min = groups[index][0];
-      const max = groups[index].slice(-1)[0];
-      return index === heatMapColors.length - 1
-        ? formatMetric(min) + " +"
-        : formatMetric(min) + " - " + formatMetric(max);
-    });
+    const columnSettings = settings.column(cols[metricIndex]);
+    const legendTitles = getLegendTitles(groups, columnSettings);
 
     const getColor = feature => {
       const value = getFeatureValue(feature);
@@ -295,7 +313,7 @@ export default class ChoroplethMap extends Component {
         className={className}
         aspectRatio={aspectRatio}
         legendTitles={legendTitles}
-        legendColors={legendColors}
+        legendColors={heatMapColors}
         gridSize={gridSize}
         hovered={hovered}
         onHoverChange={onHoverChange}
diff --git a/frontend/test/metabase/visualizations/components/ChoroplethMap.unit.spec.js b/frontend/test/metabase/visualizations/components/ChoroplethMap.unit.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..8329c1760761033c6c7509eeef61bea214729383
--- /dev/null
+++ b/frontend/test/metabase/visualizations/components/ChoroplethMap.unit.spec.js
@@ -0,0 +1,35 @@
+import { getLegendTitles } from "metabase/visualizations/components/ChoroplethMap";
+
+describe("getLegendTitles", () => {
+  it("should not format short values compactly", () => {
+    const groups = [[1.12, 1.12, 1.25], [1.32, 1.48], [9, 12, 13]];
+    const columnSettings = {
+      column: { base_type: "type/Float" },
+      number_style: "currency",
+      currency: "USD",
+      currency_style: "symbol",
+    };
+
+    const titles = getLegendTitles(groups, columnSettings);
+
+    expect(titles).toEqual(["$1.12 - $1.25", "$1.32 - $1.48", "$9.00 +"]);
+  });
+
+  it("should format long values compactly", () => {
+    const groups = [
+      [1000.12, 1100.12, 1200.25],
+      [2000.32, 2200, 2500.48],
+      [11000, 12000, 13000],
+    ];
+    const columnSettings = {
+      column: { base_type: "type/Float" },
+      number_style: "currency",
+      currency: "USD",
+      currency_style: "symbol",
+    };
+
+    const titles = getLegendTitles(groups, columnSettings);
+
+    expect(titles).toEqual(["$1.0k - $1.2k", "$2.0k - $2.5k", "$11.0k +"]);
+  });
+});