diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index ddff2bca99124015f0daf76abdebfc4eeafd25f5..84ffa4b0b597c78973eb2e3a18e131d0a8bff7e6 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -448,20 +448,6 @@ var font_fixed_metrics = [
     30, 18, 37,
     36, 22, 44 ].join(" ");
 
-// Convenience object
-var font_metrics_object = {
-    8: { w: 5, h: 11 },
-    9: { w: 6, h: 12 },
-    10: { w: 6, h: 13 },
-    12: { w: 7, h: 16 },
-    14: { w: 8, h: 17 },
-    16: { w: 10, h: 19 },
-    18: { w: 11, h: 22 },
-    24: { w: 14, h: 29 },
-    30: { w: 18, h: 37 },
-    36: { w: 22, h: 44 }
-};
-
 // Utility Functions
 
 // This is used to escape spaces and other special delimiters in FUDI
@@ -4365,16 +4351,35 @@ function gui_graph_htick(cid, tag, y, r_x, l_x, tick_pix, basex, basey) {
     g.appendChild(right_tick);
 }
 
-function gui_graph_tick_label(cid, tag, x, y, text, font, font_size, font_weight, basex, basey) {
+function gui_graph_tick_label(cid, tag, x, y, text, font, font_size, font_weight, basex, basey, tk_label_anchor) {
     var g = get_gobj(cid, tag),
-        // adjustment to center the labels
-        x_adjustment = font_metrics_object[font_size].w / 2,
-        y_adjustment = font_metrics_object[font_size].h / 2,
-        svg_text, text_node;
+        svg_text, text_node, text_anchor, alignment_baseline;
+    // We use anchor identifiers from the tk toolkit:
+    //
+    // "n" for north, or aligned at the top of the text
+    // "s" for south, or default baseline alignment
+    // "e" for east, or text-anchor at the end of the text
+    // "w" for west, or default text-anchor for left-to-right languages
+    //
+    // For x labels the tk_label_anchor will either be "n" for labels at the
+    // bottom of the graph, or "s" for labels at the top of the graph
+    //
+    // For y labels the tk_label_anchor will either be "e" for labels at the
+    // right of the graph, or "w" for labels at the right.
+    //
+    // In each case we want the label to be centered around the tick mark.
+    // So we default to value "middle" if we didn't get a value for that
+    // axis.
+    text_anchor = tk_label_anchor === "e" ? "end" :
+        tk_label_anchor === "w" ? "start" : "middle";
+    alignment_baseline = tk_label_anchor === "n" ? "hanging" :
+        tk_label_anchor === "s" ? "auto" : "middle";
     svg_text = create_item(cid, "text", {
         // need a label "y" relative to baseline
-        x: x - basex - x_adjustment,
-        y: y - basey + y_adjustment - 1,
+        x: x - basex,
+        y: y - basey,
+        "text-anchor": text_anchor,
+        "alignment-baseline": alignment_baseline,
         "font-size": pd_fontsize_to_gui_fontsize(font_size) + "px",
     });
     text_node = patchwin[cid].window.document.createTextNode(text);
diff --git a/pd/src/g_graph.c b/pd/src/g_graph.c
index fc8b2354e9cae4b2ca61b84a9e9b293d13e93931..0f39f37d07543925858fd9ce498b3940a319ff70 100644
--- a/pd/src/g_graph.c
+++ b/pd/src/g_graph.c
@@ -960,7 +960,10 @@ static void graph_vis(t_gobj *gr, t_glist *parent_glist, int vis)
         t_gobj *g;
         t_symbol *arrayname;
             /* draw a rectangle around the graph */
-
+        char *ylabelanchor =
+            (x->gl_ylabelx > 0.5*(x->gl_x1 + x->gl_x2) ? "w" : "e");
+        char *xlabelanchor =
+            (x->gl_xlabely > 0.5*(x->gl_y1 + x->gl_y2) ? "s" : "n");
         char tagbuf[MAXPDSTRING];
         sprintf(tagbuf, "%sR", tag);
 
@@ -1071,7 +1074,7 @@ static void graph_vis(t_gobj *gr, t_glist *parent_glist, int vis)
             /* draw x labels */
         for (i = 0; i < x->gl_nxlabels; i++)
         {
-            gui_vmess("gui_graph_tick_label", "xsiissisii",
+            gui_vmess("gui_graph_tick_label", "xsiissisiis",
                 glist_getcanvas(x),
                 tag,
                 (int)glist_xtopixels(x, atof(x->gl_xlabel[i]->s_name)),
@@ -1081,13 +1084,14 @@ static void graph_vis(t_gobj *gr, t_glist *parent_glist, int vis)
                 sys_hostfontsize(glist_getfont(x)),
                 sys_fontweight,
                 x1,
-                y1);
+                y1,
+                xlabelanchor);
         }
 
             /* draw y labels */
         for (i = 0; i < x->gl_nylabels; i++)
         {
-            gui_vmess("gui_graph_tick_label", "xsiissisii",
+            gui_vmess("gui_graph_tick_label", "xsiissisiis",
                 glist_getcanvas(x),
                 tag,
                 (int)glist_xtopixels(x, x->gl_ylabelx),
@@ -1097,7 +1101,8 @@ static void graph_vis(t_gobj *gr, t_glist *parent_glist, int vis)
                 sys_hostfontsize(glist_getfont(x)),
                 sys_fontweight,
                 x1,
-                y1);
+                y1,
+                ylabelanchor);
         }
 
             /* draw contents of graph as glist */