diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index 67015c32264e7173c2b1d661f2aed02f1eeea399..2b45f8133010039e0d17aad2c5fc47d69fc248cd 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -108,7 +108,6 @@ uint16_t max_display_update_time = 0;
     extern bool powersupply_on;
   #endif
 
-
   ////////////////////////////////////////////
   ///////////////// Menu Tree ////////////////
   ////////////////////////////////////////////
@@ -790,7 +789,7 @@ void kill_screen(const char* lcd_msg) {
       encoderPosition = 0;
       lcd_implementation_drawmenu_static(0, PSTR(MSG_PROGRESS_BAR_TEST), true, true);
       lcd.setCursor((LCD_WIDTH) / 2 - 2, LCD_HEIGHT - 2);
-      lcd.print(itostr3(bar_percent)); lcd.print('%');
+      lcd.print(itostr3(bar_percent)); lcd.write('%');
       lcd.setCursor(0, LCD_HEIGHT - 1); lcd_draw_progress_bar(bar_percent);
     }
 
@@ -2145,8 +2144,12 @@ void kill_screen(const char* lcd_msg) {
     void _lcd_ubl_map_homing() {
       if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_HOMING), NULL);
       lcdDrawUpdate = LCDVIEW_CALL_NO_REDRAW;
-      if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS])
+      if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) {
+        #if DISABLED(DOGLCD)
+          lcd_set_ubl_map_plot_chars();
+        #endif
         lcd_goto_screen(_lcd_ubl_output_map_lcd);
+      }
     }
 
     /**
@@ -2163,97 +2166,6 @@ void kill_screen(const char* lcd_msg) {
       enqueue_and_echo_command(ubl_lcd_gcode);
     }
 
-  #if ENABLED(DOGLCD)
-
-    /**
-     * UBL LCD "radar" map data
-     */
-    #define MAP_UPPER_LEFT_CORNER_X 35  // These probably should be moved to the .h file  But for now,
-    #define MAP_UPPER_LEFT_CORNER_Y 8   // it is easier to play with things having them here
-    #define MAP_MAX_PIXELS_X        53
-    #define MAP_MAX_PIXELS_Y        49
-
-    void _lcd_ubl_plot_drawing_prep() {
-      uint8_t i, j, x_offset, y_offset, x_map_pixels, y_map_pixels,
-              pixels_per_X_mesh_pnt, pixels_per_Y_mesh_pnt, inverted_y;
-
-      /*********************************************************/
-      /************ Scale the box pixels appropriately *********/
-      /*********************************************************/
-      x_map_pixels = ((MAP_MAX_PIXELS_X - 4) / (GRID_MAX_POINTS_X)) * (GRID_MAX_POINTS_X);
-      y_map_pixels = ((MAP_MAX_PIXELS_Y - 4) / (GRID_MAX_POINTS_Y)) * (GRID_MAX_POINTS_Y);
-
-      pixels_per_X_mesh_pnt = x_map_pixels / (GRID_MAX_POINTS_X);
-      pixels_per_Y_mesh_pnt = y_map_pixels / (GRID_MAX_POINTS_Y);
-
-      x_offset = MAP_UPPER_LEFT_CORNER_X + 1 + (MAP_MAX_PIXELS_X - x_map_pixels - 2) / 2;
-      y_offset = MAP_UPPER_LEFT_CORNER_Y + 1 + (MAP_MAX_PIXELS_Y - y_map_pixels - 2) / 2;
-
-      /*********************************************************/
-      /************ Clear the Mesh Map Box**********************/
-      /*********************************************************/
-
-      u8g.setColorIndex(1);  // First draw the bigger box in White so we have a border around the mesh map box
-      u8g.drawBox(x_offset - 2, y_offset - 2, x_map_pixels + 4, y_map_pixels + 4);
-
-      u8g.setColorIndex(0);  // Now actually clear the mesh map box
-      u8g.drawBox(x_offset, y_offset, x_map_pixels, y_map_pixels);
-
-      /*********************************************************/
-      /************ Display Mesh Point Locations ***************/
-      /*********************************************************/
-
-      u8g.setColorIndex(1);
-      for (i = 0; i < GRID_MAX_POINTS_X; i++) {
-        for (j = 0; j < GRID_MAX_POINTS_Y; j++) {
-          u8g.drawBox(x_offset + i * pixels_per_X_mesh_pnt + pixels_per_X_mesh_pnt / 2,
-                      y_offset + j * pixels_per_Y_mesh_pnt + pixels_per_Y_mesh_pnt / 2, 1, 1);
-        }
-      }
-
-      /*********************************************************/
-      /************ Fill in the Specified Mesh Point ***********/
-      /*********************************************************/
-
-      inverted_y = GRID_MAX_POINTS_Y - y_plot - 1;    // The origin is typically in the lower right corner.  We need to
-                                                      // invert the Y to get it to plot in the right location.
-      u8g.drawBox(x_offset + x_plot * pixels_per_X_mesh_pnt, y_offset + inverted_y * pixels_per_Y_mesh_pnt,
-                    pixels_per_X_mesh_pnt, pixels_per_Y_mesh_pnt);
-
-      /*********************************************************/
-      /************** Put Relevent Text on Display *************/
-      /*********************************************************/
-
-      // Show X and Y positions at top of screen
-      u8g.setColorIndex(1);
-      u8g.setPrintPos(5, 7);
-      lcd_print("X:");
-      lcd_print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]))));
-      u8g.setPrintPos(74, 7);
-      lcd_print("Y:");
-      lcd_print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]))));
-
-      // Print plot position
-      u8g.setPrintPos(5, 64);
-      lcd_print('(');
-      u8g.print(x_plot);
-      lcd_print(',');
-      u8g.print(y_plot);
-      lcd_print(')');
-
-      // Show the location value
-      u8g.setPrintPos(74, 64);
-      lcd_print("Z:");
-      if (!isnan(ubl.z_values[x_plot][y_plot])) {
-        lcd_print(ftostr43sign(ubl.z_values[x_plot][y_plot]));
-      }
-      else {
-        lcd_print(" -----");
-      }
-    }
-
-  #endif // DOGLCD
-
     /**
      * UBL LCD Map Movement
      */
@@ -2309,19 +2221,13 @@ void kill_screen(const char* lcd_msg) {
         #if IS_KINEMATIC
           n_edit_pts = 9; //TODO: Delta accessible edit points
         #else
-          if (x_plot < 1 || x_plot >= GRID_MAX_POINTS_X - 1)
-            if (y_plot < 1 || y_plot >= GRID_MAX_POINTS_Y - 1) n_edit_pts = 4; // Corners
-            else n_edit_pts = 6;
-          else if (y_plot < 1 || y_plot >= GRID_MAX_POINTS_Y - 1) n_edit_pts = 6; // Edges
-          else n_edit_pts = 9; // Field
+          const bool xc = WITHIN(x_plot, 1, GRID_MAX_POINTS_X - 2),
+                     yc = WITHIN(y_plot, 1, GRID_MAX_POINTS_Y - 2);
+          n_edit_pts = yc ? (xc ? 9 : 6) : (xc ? 6 : 4); // Corners
         #endif
 
         if (lcdDrawUpdate) {
-          #if ENABLED(DOGLCD)
-            _lcd_ubl_plot_drawing_prep();
-          #else
-            _lcd_ubl_output_char_lcd();
-          #endif
+          lcd_implementation_ubl_plot(x_plot, y_plot);
 
           ubl_map_move_to_xy(); // Move to current location
 
diff --git a/Marlin/ultralcd_impl_DOGM.h b/Marlin/ultralcd_impl_DOGM.h
index 406f1c317625e4ce0feac5c8add80ddd9c7a56d2..c9cbf452e55901d36643635f237393d2fb3753fa 100644
--- a/Marlin/ultralcd_impl_DOGM.h
+++ b/Marlin/ultralcd_impl_DOGM.h
@@ -688,7 +688,7 @@ static void lcd_implementation_status_screen() {
 
   #define STATUS_BASELINE (55 + INFO_FONT_HEIGHT)
 
-  if (PAGE_CONTAINS(STATUS_BASELINE + 1 - INFO_FONT_HEIGHT, STATUS_BASELINE)) {
+  if (PAGE_CONTAINS(STATUS_BASELINE - (INFO_FONT_HEIGHT - 1), STATUS_BASELINE)) {
     u8g.setPrintPos(0, STATUS_BASELINE);
 
     #if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT)
@@ -939,6 +939,95 @@ static void lcd_implementation_status_screen() {
 
   #endif // SDSUPPORT
 
+  #if ENABLED(AUTO_BED_LEVELING_UBL)
+
+    /**
+     * UBL LCD "radar" map data
+     */
+    #define MAP_UPPER_LEFT_CORNER_X 35  // These probably should be moved to the .h file  But for now,
+    #define MAP_UPPER_LEFT_CORNER_Y  8  // it is easier to play with things having them here
+    #define MAP_MAX_PIXELS_X        53
+    #define MAP_MAX_PIXELS_Y        49
+
+    void lcd_implementation_ubl_plot(const uint8_t x_plot, const uint8_t y_plot) {
+      // Scale the box pixels appropriately
+      uint8_t x_map_pixels = ((MAP_MAX_PIXELS_X - 4) / (GRID_MAX_POINTS_X)) * (GRID_MAX_POINTS_X),
+              y_map_pixels = ((MAP_MAX_PIXELS_Y - 4) / (GRID_MAX_POINTS_Y)) * (GRID_MAX_POINTS_Y),
+
+              pixels_per_X_mesh_pnt = x_map_pixels / (GRID_MAX_POINTS_X),
+              pixels_per_Y_mesh_pnt = y_map_pixels / (GRID_MAX_POINTS_Y),
+
+              x_offset = MAP_UPPER_LEFT_CORNER_X + 1 + (MAP_MAX_PIXELS_X - x_map_pixels - 2) / 2,
+              y_offset = MAP_UPPER_LEFT_CORNER_Y + 1 + (MAP_MAX_PIXELS_Y - y_map_pixels - 2) / 2;
+
+      // Clear the Mesh Map
+
+      if (PAGE_CONTAINS(y_offset - 2, y_offset + y_map_pixels + 4)) {
+        u8g.setColorIndex(1);  // First draw the bigger box in White so we have a border around the mesh map box
+        u8g.drawBox(x_offset - 2, y_offset - 2, x_map_pixels + 4, y_map_pixels + 4);
+        if (PAGE_CONTAINS(y_offset, y_offset + y_map_pixels)) {
+          u8g.setColorIndex(0);  // Now actually clear the mesh map box
+          u8g.drawBox(x_offset, y_offset, x_map_pixels, y_map_pixels);
+        }
+      }
+
+      // Display Mesh Point Locations
+
+      u8g.setColorIndex(1);
+      const uint8_t sx = x_offset + pixels_per_X_mesh_pnt / 2;
+            uint8_t  y = y_offset + pixels_per_Y_mesh_pnt / 2;
+      for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++, y += pixels_per_Y_mesh_pnt)
+        if (PAGE_CONTAINS(y, y))
+          for (uint8_t i = 0, x = sx; i < GRID_MAX_POINTS_X; i++, x += pixels_per_X_mesh_pnt)
+            u8g.drawBox(sx, y, 1, 1);
+
+      // Fill in the Specified Mesh Point
+
+      uint8_t inverted_y = GRID_MAX_POINTS_Y - y_plot - 1;  // The origin is typically in the lower right corner.  We need to
+                                                            // invert the Y to get it to plot in the right location.
+
+      const uint8_t by = y_offset + inverted_y * pixels_per_Y_mesh_pnt;
+      if (PAGE_CONTAINS(by, by + pixels_per_Y_mesh_pnt))
+        u8g.drawBox(
+          x_offset + x_plot * pixels_per_X_mesh_pnt, by,
+          pixels_per_X_mesh_pnt, pixels_per_Y_mesh_pnt
+        );
+
+      // Put Relevant Text on Display
+
+      // Show X and Y positions at top of screen
+      u8g.setColorIndex(1);
+      if (PAGE_UNDER(7)) {
+        u8g.setPrintPos(5, 7);
+        lcd_print("X:");
+        lcd_print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]))));
+        u8g.setPrintPos(74, 7);
+        lcd_print("Y:");
+        lcd_print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]))));
+      }
+
+      // Print plot position
+      if (PAGE_CONTAINS(64 - (INFO_FONT_HEIGHT - 1), 64)) {
+        u8g.setPrintPos(5, 64);
+        lcd_print('(');
+        u8g.print(x_plot);
+        lcd_print(',');
+        u8g.print(y_plot);
+        lcd_print(')');
+
+        // Show the location value
+        u8g.setPrintPos(74, 64);
+        lcd_print("Z:");
+        if (!isnan(ubl.z_values[x_plot][y_plot]))
+          lcd_print(ftostr43sign(ubl.z_values[x_plot][y_plot]));
+        else
+          lcd_printPGM(PSTR(" -----"));
+      }
+
+    }
+
+  #endif // AUTO_BED_LEVELING_UBL
+
 #endif // ULTIPANEL
 
 #endif // __ULTRALCD_IMPL_DOGM_H
diff --git a/Marlin/ultralcd_impl_HD44780.h b/Marlin/ultralcd_impl_HD44780.h
index 71496ae75cf7d7f865c586031d4c57f9335c7ac1..2824ed0882aa3ea5f0ab7203cb3d48ea8635e839 100644
--- a/Marlin/ultralcd_impl_HD44780.h
+++ b/Marlin/ultralcd_impl_HD44780.h
@@ -31,6 +31,10 @@
 #include "utility.h"
 #include "duration_t.h"
 
+#if ENABLED(AUTO_BED_LEVELING_UBL)
+  #include "ubl.h"
+#endif
+
 extern volatile uint8_t buttons;  //an extended version of the last checked buttons in a bit array.
 
 ////////////////////////////////////
@@ -417,7 +421,7 @@ void lcd_printPGM_utf(const char *str, uint8_t n=LCD_WIDTH) {
   void lcd_erase_line(const int16_t line) {
     lcd.setCursor(0, line);
     for (uint8_t i = LCD_WIDTH + 1; --i;)
-      lcd.print(' ');
+      lcd.write(' ');
   }
 
   // Scroll the PSTR 'text' in a 'len' wide field for 'time' milliseconds at position col,line
@@ -434,9 +438,9 @@ void lcd_printPGM_utf(const char *str, uint8_t n=LCD_WIDTH) {
 
   static void logo_lines(const char* const extra) {
     int16_t indent = (LCD_WIDTH - 8 - lcd_strlen_P(extra)) / 2;
-    lcd.setCursor(indent, 0); lcd.print('\x00'); lcd_printPGM(PSTR( "------" ));  lcd.print('\x01');
+    lcd.setCursor(indent, 0); lcd.print('\x00'); lcd_printPGM(PSTR( "------" ));  lcd.write('\x01');
     lcd.setCursor(indent, 1);                    lcd_printPGM(PSTR("|Marlin|"));  lcd_printPGM(extra);
-    lcd.setCursor(indent, 2); lcd.print('\x02'); lcd_printPGM(PSTR( "------" ));  lcd.print('\x03');
+    lcd.setCursor(indent, 2); lcd.write('\x02'); lcd_printPGM(PSTR( "------" ));  lcd.write('\x03');
   }
 
   void bootscreen() {
@@ -577,11 +581,11 @@ FORCE_INLINE void _draw_axis_label(const AxisEnum axis, const char* const pstr,
     lcd_printPGM(pstr);
   else {
     if (!axis_homed[axis])
-      lcd.print('?');
+      lcd.write('?');
     else {
       #if DISABLED(DISABLE_REDUCED_ACCURACY_WARNING)
         if (!axis_known_position[axis])
-          lcd.print(' ');
+          lcd.write(' ');
         else
       #endif
       lcd_printPGM(pstr);
@@ -598,7 +602,7 @@ FORCE_INLINE void _draw_heater_status(const int8_t heater, const char prefix, co
   if (prefix >= 0) lcd.print(prefix);
 
   lcd.print(itostr3(t1 + 0.5));
-  lcd.print('/');
+  lcd.write('/');
 
   #if HEATER_IDLE_HANDLER
     const bool is_idle = (!isBed ? thermalManager.is_heater_idle(heater) :
@@ -610,9 +614,9 @@ FORCE_INLINE void _draw_heater_status(const int8_t heater, const char prefix, co
     );
 
     if (!blink && is_idle) {
-      lcd.print(' ');
-      if (t2 >= 10) lcd.print(' ');
-      if (t2 >= 100) lcd.print(' ');
+      lcd.write(' ');
+      if (t2 >= 10) lcd.write(' ');
+      if (t2 >= 100) lcd.write(' ');
     }
     else
   #endif
@@ -620,8 +624,8 @@ FORCE_INLINE void _draw_heater_status(const int8_t heater, const char prefix, co
 
   if (prefix >= 0) {
     lcd.print((char)LCD_DEGREE_CHAR);
-    lcd.print(' ');
-    if (t2 < 10) lcd.print(' ');
+    lcd.write(' ');
+    if (t2 < 10) lcd.write(' ');
   }
 }
 
@@ -738,7 +742,7 @@ static void lcd_implementation_status_screen() {
           lcd.print(itostr3(card.percentDone()));
         else
           lcd_printPGM(PSTR("---"));
-          lcd.print('%');
+          lcd.write('%');
       #endif // SDSUPPORT
 
     #else // LCD_WIDTH >= 20
@@ -760,7 +764,7 @@ static void lcd_implementation_status_screen() {
         _draw_axis_label(X_AXIS, PSTR(MSG_X), blink);
         lcd.print(ftostr4sign(current_position[X_AXIS]));
 
-        lcd.print(' ');
+        lcd.write(' ');
 
         _draw_axis_label(Y_AXIS, PSTR(MSG_Y), blink);
         lcd.print(ftostr4sign(current_position[Y_AXIS]));
@@ -784,7 +788,7 @@ static void lcd_implementation_status_screen() {
     lcd.setCursor(0, 2);
     lcd.print((char)LCD_FEEDRATE_CHAR);
     lcd.print(itostr3(feedrate_percentage));
-    lcd.print('%');
+    lcd.write('%');
 
     #if LCD_WIDTH >= 20 && ENABLED(SDSUPPORT)
 
@@ -794,7 +798,7 @@ static void lcd_implementation_status_screen() {
         lcd.print(itostr3(card.percentDone()));
       else
         lcd_printPGM(PSTR("---"));
-      lcd.print('%');
+      lcd.write('%');
 
     #endif // LCD_WIDTH >= 20 && SDSUPPORT
 
@@ -833,7 +837,7 @@ static void lcd_implementation_status_screen() {
       lcd.print(ftostr12ns(filament_width_meas));
       lcd_printPGM(PSTR(" V"));
       lcd.print(itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]));
-      lcd.print('%');
+      lcd.write('%');
       return;
     }
 
@@ -854,10 +858,10 @@ static void lcd_implementation_status_screen() {
           lcd_print_utf(stat);                                  // The string leaves space
           chars -= slen - status_scroll_pos;                    // Amount of space left
         }
-        lcd.print('.');                                         // Always at 1+ spaces left, draw a dot
+        lcd.write('.');                                         // Always at 1+ spaces left, draw a dot
         if (--chars) {
           if (status_scroll_pos < slen + 1)                     // Draw a second dot if there's space
-            --chars, lcd.print('.');
+            --chars, lcd.write('.');
           if (chars) lcd_print_utf(lcd_status_message, chars);  // Print a second copy of the message
         }
       }
@@ -893,7 +897,7 @@ static void lcd_implementation_status_screen() {
     lcd.setCursor(0, row);
     if (center && !valstr) {
       int8_t pad = (LCD_WIDTH - lcd_strlen_P(pstr)) / 2;
-      while (--pad >= 0) { lcd.print(' '); n--; }
+      while (--pad >= 0) { lcd.write(' '); n--; }
     }
     while (n > 0 && (c = pgm_read_byte(pstr))) {
       n -= charset_mapper(c);
@@ -903,7 +907,7 @@ static void lcd_implementation_status_screen() {
       n -= charset_mapper(c);
       valstr++;
     }
-    while (n-- > 0) lcd.print(' ');
+    while (n-- > 0) lcd.write(' ');
   }
 
   static void lcd_implementation_drawmenu_generic(const bool sel, const uint8_t row, const char* pstr, const char pre_char, const char post_char) {
@@ -915,7 +919,7 @@ static void lcd_implementation_status_screen() {
       n -= charset_mapper(c);
       pstr++;
     }
-    while (n--) lcd.print(' ');
+    while (n--) lcd.write(' ');
     lcd.print(post_char);
   }
 
@@ -928,8 +932,8 @@ static void lcd_implementation_status_screen() {
       n -= charset_mapper(c);
       pstr++;
     }
-    lcd.print(':');
-    while (n--) lcd.print(' ');
+    lcd.write(':');
+    while (n--) lcd.write(' ');
     lcd_print(data);
   }
   static void lcd_implementation_drawmenu_setting_edit_generic_P(const bool sel, const uint8_t row, const char* pstr, const char pre_char, const char* const data) {
@@ -941,8 +945,8 @@ static void lcd_implementation_status_screen() {
       n -= charset_mapper(c);
       pstr++;
     }
-    lcd.print(':');
-    while (n--) lcd.print(' ');
+    lcd.write(':');
+    while (n--) lcd.write(' ');
     lcd_printPGM(data);
   }
 
@@ -977,10 +981,10 @@ static void lcd_implementation_status_screen() {
     lcd.setCursor(1, 1);
     lcd_printPGM(pstr);
     if (value != NULL) {
-      lcd.print(':');
+      lcd.write(':');
       const uint8_t valrow = (lcd_strlen_P(pstr) + 1 + lcd_strlen(value) + 1) > (LCD_WIDTH - 2) ? 2 : 1;  // Value on the next row if it won't fit
       lcd.setCursor((LCD_WIDTH - 1) - (lcd_strlen(value) + 1), valrow);                                   // Right-justified, padded by spaces
-      lcd.print(' ');                                                                                     // overwrite char if value gets shorter
+      lcd.write(' ');                                                                                     // overwrite char if value gets shorter
       lcd_print(value);
     }
   }
@@ -1001,7 +1005,7 @@ static void lcd_implementation_status_screen() {
         n -= charset_mapper(c);
         filename++;
       }
-      while (n--) lcd.print(' ');
+      while (n--) lcd.write(' ');
       lcd.print(post_char);
     }
 
@@ -1079,10 +1083,152 @@ static void lcd_implementation_status_screen() {
 
 #endif // LCD_HAS_STATUS_INDICATORS
 
-#ifdef AUTO_BED_LEVELING_UBL
-    void lcd_return_to_status();       // These are just place holders for the 20x4 LCD work that
-    void _lcd_ubl_output_char_lcd() {  // is coming up very soon.   Soon this will morph into the
-      lcd_return_to_status();          // real code.
+#if ENABLED(AUTO_BED_LEVELING_UBL)
+
+    /* 
+     * These are just basic data for the 20x4 LCD work that
+     * is coming up very soon.
+     * Soon this will morph into a map code.
+     */
+
+    /**
+    Possible map screens:
+
+    16x2   |X000.00  Y000.00|
+           |(00,00)  Z00.000|
+
+    20x2   | X:000.00  Y:000.00 |
+           | (00,00)   Z:00.000 |
+
+    16x4   |+-------+(00,00)|
+           ||       |X000.00|
+           ||       |Y000.00|
+           |+-------+Z00.000|
+
+    20x4   | +-------+  (00,00) |
+           | |       |  X:000.00|
+           | |       |  Y:000.00|
+           | +-------+  Z:00.000|
+    */
+
+    void lcd_set_ubl_map_plot_chars() {
+      #if LCD_HEIGHT > 3
+        //#include "_ubl_lcd_map_characters.h"
+        const static byte _lcd_box_top[8] PROGMEM = {
+          B11111,
+          B00000,
+          B00000,
+          B00000,
+          B00000,
+          B00000,
+          B00000,
+          B00000
+        };
+        const static byte _lcd_box_bottom[8] PROGMEM = {
+          B00000,
+          B00000,
+          B00000,
+          B00000,
+          B00000,
+          B00000,
+          B00000,
+          B11111
+        };
+        createChar_P(1, _lcd_box_top);
+        createChar_P(2, _lcd_box_bottom);
+      #endif
+    }
+
+    void lcd_implementation_ubl_plot(const uint8_t x_plot, const uint8_t y_plot) {
+
+      #if LCD_WIDTH >= 20
+        #define _LCD_W_POS 12
+        #define _PLOT_X 1
+        #define _MAP_X 3
+        #define _LABEL(C,X,Y) lcd.setCursor(X, Y); lcd.print(C)
+        #define _XLABEL(X,Y) _LABEL("X:",X,Y)
+        #define _YLABEL(X,Y) _LABEL("Y:",X,Y)
+        #define _ZLABEL(X,Y) _LABEL("Z:",X,Y)
+      #else
+        #define _LCD_W_POS 8
+        #define _PLOT_X 0
+        #define _MAP_X 1
+        #define _LABEL(X,Y,C) lcd.setCursor(X, Y); lcd.write(C)
+        #define _XLABEL(X,Y) _LABEL('X',X,Y)
+        #define _YLABEL(X,Y) _LABEL('Y',X,Y)
+        #define _ZLABEL(X,Y) _LABEL('Z',X,Y)
+      #endif
+
+      #if LCD_HEIGHT <= 3   // 16x2 or 20x2 display
+
+        /**
+         * Show X and Y positions
+         */
+        _XLABEL(_PLOT_X, 0);
+        lcd.print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]))));
+
+        _YLABEL(_LCD_W_POS, 0);
+        lcd.print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]))));
+
+        lcd.setCursor(_PLOT_X, 0);
+
+      #else                 // 16x4 or 20x4 display
+
+        /**
+         * Draw the Mesh Map Box
+         */
+        uint8_t m;
+        lcd.setCursor(_MAP_X, 0); for (m = 0; m < 5; m++) lcd.write(1); // Top
+        lcd.setCursor(_MAP_X, 3); for (m = 0; m < 5; m++) lcd.write(2); // Bottom
+        for (m = 0; m <= 3; m++) {
+          lcd.setCursor(2, m); lcd.write('|'); // Left
+          lcd.setCursor(8, m); lcd.write('|'); // Right
+        }
+
+        lcd.setCursor(_LCD_W_POS, 0);
+
+      #endif
+
+      /**
+       * Print plot position
+       */
+      lcd.write('(');
+      lcd.print(x_plot);
+      lcd.write(',');
+      lcd.print(y_plot);
+      lcd.write(')');
+
+      #if LCD_HEIGHT <= 3   // 16x2 or 20x2 display
+
+        /**
+         * Print Z values
+         */
+        _ZLABEL(_LCD_W_POS, 1);
+        if (!isnan(ubl.z_values[x_plot][y_plot]))
+          lcd.print(ftostr43sign(ubl.z_values[x_plot][y_plot]));
+        else
+          lcd_printPGM(PSTR(" -----"));
+
+      #else                 // 16x4 or 20x4 display
+
+        /**
+         * Show all values at right of screen
+         */
+        _XLABEL(_LCD_W_POS, 1);
+        lcd.print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]))));
+        _YLABEL(_LCD_W_POS, 2);
+        lcd.print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]))));
+
+        /**
+         * Show the location value
+         */
+        _ZLABEL(_LCD_W_POS, 3);
+        if (!isnan(ubl.z_values[x_plot][y_plot]))
+          lcd.print(ftostr43sign(ubl.z_values[x_plot][y_plot]));
+        else
+          lcd_printPGM(PSTR(" -----"));
+
+      #endif // LCD_HEIGHT > 3
     }
 
 #endif // AUTO_BED_LEVELING_UBL