Text and Annotations in JavaScript

How to add text labels and annotations to D3.js-based plots in javascript.


New to Plotly?

Plotly is a free and open-source graphing library for JavaScript. We recommend you read our Getting Started guide for the latest installation or upgrade instructions, then move on to our Plotly Fundamentals tutorials or dive straight in to some Basic Charts tutorials.

var trace1 = {
  x: [0, 1, 2],
  y: [1, 1, 1],
  mode: 'lines+markers+text',
  name: 'Lines, Markers and Text',
  text: ['Text A', 'Text B', 'Text C'],
  textposition: 'top',
  type: 'scatter'
};
var trace2 = {
  x: [0, 1, 2],
  y: [2, 2, 2],
  mode: 'markers+text',
  name: 'Markers and Text',
  text: ['Text D', 'Text E', 'Text F'],
  textposition: 'bottom',
  type: 'scatter'
};
var trace3 = {
  x: [0, 1, 2],
  y: [3, 3, 3],
  mode: 'lines+text',
  name: 'Lines and Text',
  text: ['Text G', 'Text H', 'Text I'],
  textposition: 'bottom',
  type: 'scatter'
};
var data = [trace1, trace2, trace3];
var layout = {showlegend: false};
Plotly.newPlot('myDiv', data, layout);
Plotly.newPlot('myDiv', [{
  x: [1,2,3],
  y: [2,1,2]
}], {
  annotations: [{
    xref: 'paper',
    yref: 'paper',
    x: 0,
    xanchor: 'right',
    y: 1,
    yanchor: 'bottom',
    text: 'X axis label',
    showarrow: false
  }, {
    xref: 'paper',
    yref: 'paper',
    x: 1,
    xanchor: 'left',
    y: 0,
    yanchor: 'top',
    text: 'Y axis label',
    showarrow: false
  }]
  
})
var trace1 = {
  x: [0, 1, 2, 3, 4, 5, 6, 7, 8],
  y: [0, 1, 3, 2, 4, 3, 4, 6, 5],
  type: 'scatter'
};
var trace2 = {
  x: [0, 1, 2, 3, 4, 5, 6, 7, 8],
  y: [0, 4, 5, 1, 2, 2, 3, 4, 2],
  type: 'scatter'
};
var data = [trace1, trace2];
var layout = {
  showlegend: false,
  annotations: [
    {
      x: 2,
      y: 5,
      xref: 'x',
      yref: 'y',
      text: 'Annotation Text',
      showarrow: true,
      arrowhead: 7,
      ax: 0,
      ay: -40
    }
  ]
};
Plotly.newPlot('myDiv', data, layout);

If the x or y positions of an annotation reference a log axis, you need to provide that position as a log10 value when adding the annotation. In this example, the yaxis is a log axis so we pass the log10 value of 1000 to the annotation's y position.

var dates = [
    "2024-01-01",
    "2024-01-02",
    "2024-01-03",
    "2024-01-04",
    "2024-01-05",
    "2024-01-06",
];

var y_values = [1, 30, 70, 100, 1000, 10000000];

var trace1 = {
    x: dates,
    y: y_values,
    mode: 'lines+markers',
    type: 'scatter'
};

var layout = {
    yaxis: {
        type: 'log',
    },
    annotations: [
        {
            x: '2024-01-05',
            y: Math.log10(1000),
            text: 'Log axis annotation',
            showarrow: true,
            xanchor: 'right',
        }
    ]
};

var data = [trace1];

Plotly.newPlot('myDiv', data, layout);
var trace1 = {
  x: [0, 1, 2, 3, 4, 5, 6, 7, 8],
  y: [0, 1, 3, 2, 4, 3, 4, 6, 5],
  type: 'scatter'
};
var trace2 = {
  x: [0, 1, 2, 3, 4, 5, 6, 7, 8],
  y: [0, 4, 5, 1, 2, 2, 3, 4, 2],
  type: 'scatter'
};
var data = [trace1, trace2];
var layout = {
  showlegend: false,
  annotations: [
    {
      x: 2,
      y: 5,
      xref: 'x',
      yref: 'y',
      text: 'Annotation Text',
      showarrow: true,
      arrowhead: 7,
      ax: 0,
      ay: -40
    },
    {
      x: 4,
      y: 4,
      xref: 'x',
      yref: 'y',
      text: 'Annotation Text 2',
      showarrow: true,
      arrowhead: 7,
      ax: 0,
      ay: -40
    }
  ]
};
Plotly.newPlot('myDiv', data, layout);
var trace0 = {
  x: [1, 2, 3],
  y: [4, 5, 6],
  type: 'scatter'
};

var trace1 = {
  x: [20, 30, 40],
  y: [50, 60, 70],
  xaxis: 'x2',
  yaxis: 'y2',
  type: 'scatter'
};

var data = [trace0, trace1];

var layout = {
  title: 'Subplot Annotations',
  xaxis: {domain: [0, 0.45]},
  yaxis2: {anchor: 'x2'},
  xaxis2: {domain: [0.55, 1]},
  annotations: [
    {
      x: 2,
      y: 5,
      xref: 'x',
      yref: 'y',
      text: 'Annotation A',
      showarrow: true,
      arrowhead: 3,
      ax: -30,
      ay: -40
    },
    {
      x: 30,
      y: 60,
      xref: 'x2',
      yref: 'y2',
      text: 'Annotation B',
      showarrow: true,
      arrowhead: 2,
      ax: -25,
      ay: -40
    }
  ]
};

Plotly.newPlot('myDiv', data, layout);
var data = [{
    type: "scatter3d",
    x: ["2017-01-01", "2017-02-10", "2017-03-20"],
    y: ["A", "B", "C"],
    z: [1, 1e3, 1e5]
 }]

var layout = {
    scene: {
      camera: {
        eye: {x: 2.1, y: 0.1, z: 0.9}
      },
      xaxis: {
        title: ""
      },
      yaxis: {
        title: ""
      },
      zaxis: {
        type: "log",
        title: ""
      },
      annotations: [{
        showarrow: false,
        x: "2017-01-01",
        y: "A",
        z: 0,
        text: "Point 1",
        font: {
          color: "black",
          size: 12
        },
        xanchor: "left",
        xshift: 10,
        opacity: 0.7
      }, {
        x: "2017-02-10",
        y: "B",
        z: 4,
        text: "Point 2",
        textangle: 0,
        ax: 0,
        ay: -75,
        font: {
          color: "black",
          size: 12
        },
        arrowcolor: "black",
        arrowsize: 3,
        arrowwidth: 1,
        arrowhead: 1
      }, {
        x: "2017-03-20",
        y: "C",
        z: 5,
        ax: 50,
        ay: 0,
        text: "Point 3",
        arrowhead: 1,
        xanchor: "left",
        yanchor: "bottom"
      }]
}
}

Plotly.newPlot('myDiv', data, layout);
var trace1 = {
  x: [0, 1, 2],
  y: [1, 1, 1],
  mode: 'lines+markers+text',
  name: 'Lines, Markers and Text',
  text: ['Text A', 'Text B', 'Text C'],
  textposition: 'top right',
  textfont: {
    family: 'sans serif',
    size: 18,
    color: '#1f77b4'
  },
  type: 'scatter'
};
var trace2 = {
  x: [0, 1, 2],
  y: [2, 2, 2],
  mode: 'lines+markers+text',
  name: 'Lines and Text',
  text: ['Text G', 'Text H', 'Text I'],
  textposition: 'bottom',
  textfont: {
    family: 'sans serif',
    size: 18,
    color: '#ff7f0e'
  },
  type: 'scatter'
};
var data = [trace1, trace2];
var layout = {showlegend: false};
Plotly.newPlot('myDiv', data, layout);
var trace1 = {
  x: [0, 1, 2, 3, 4, 5, 6, 7, 8],
  y: [0, 1, 3, 2, 4, 3, 4, 6, 5],
  type: 'scatter'
};
var trace2 = {
  x: [0, 1, 2, 3, 4, 5, 6, 7, 8],
  y: [0, 4, 5, 1, 2, 2, 3, 4, 2],
  type: 'scatter'
};
var data = [trace1, trace2];
var layout = {
  showlegend: false,
  annotations: [
    {
      x: 2,
      y: 5,
      xref: 'x',
      yref: 'y',
      text: 'max=5',
      showarrow: true,
      font: {
        family: 'Courier New, monospace',
        size: 16,
        color: '#ffffff'
      },
      align: 'center',
      arrowhead: 2,
      arrowsize: 1,
      arrowwidth: 2,
      arrowcolor: '#636363',
      ax: 20,
      ay: -30,
      bordercolor: '#c7c7c7',
      borderwidth: 2,
      borderpad: 4,
      bgcolor: '#ff7f0e',
      opacity: 0.8
    }
  ]
};
Plotly.newPlot('myDiv', data, layout);
var myPlot = document.getElementById('myDiv'),
   N = 12,
    x = d3.range(N).map( d3.random.normal(3) ),
    y1 = d3.range(N).map( d3.random.normal(4) ),
    y2 = d3.range(N).map( d3.random.normal(4) ),
    y3 = d3.range(N).map( d3.random.normal(4) ),
    months = ['Jan', 'Feb', 'Mar',
          'Apr', 'May', 'June',
          'July', 'Aug', 'Sept',
          'Oct', 'Nov', 'Dec'],
    data = [{ x:x, y:y1,
             type:'scatter', mode:'markers',
         name:'2014', text: months,
             marker:{color:'rgba(200, 50, 100, .7)',
                      size:16}
             },
            { x:x, y:y2,
             type:'scatter', mode:'markers',
         name:'2015', text:months,
             marker:{color:'rgba(120, 20, 130, .7)',
                     size:16}
             },
            { x:x, y:y3,
             type:'scatter', mode:'markers',
         name: '2016', text:months,
             marker:{color:'rgba(10, 180, 180, .8)',
                     size:16}}];
    layout = {
        hovermode:'closest',
        title:'<b>Formatting Annotations</b> <br> click on a point to plot an annotation',
        xaxis:{zeroline:false, title: 'Value A'},
        yaxis:{zeroline:false, title: 'Value B'}
     };

Plotly.newPlot('myDiv', data, layout);

myPlot.on('plotly_click',
    function(data){
      var point = data.points[0],
          newAnnotation = {
            x: point.xaxis.d2l(point.x),
            y: point.yaxis.d2l(point.y),
            arrowhead: 6,
            ax: 0,
            ay: -80,
            bgcolor: 'rgba(255, 255, 255, 0.9)',
            arrowcolor: point.fullData.marker.color,
            font: {size:12},
            bordercolor: point.fullData.marker.color,
            borderwidth: 3,
            borderpad: 4,
            text: '<i>Series Identification</i>' + <br>
                  '<b>Year</b>       '+(point.data.name) + '<br>' +
                  '<i>Point Identification</i><br>' +
                  '<b>Month</b>      '+ (months[point.pointNumber]) +
                  '<br><i>Point Values</i><br>' +
                  '<b>A</b>     '+(point.x).toPrecision(4) +
                  '<br><b>B</b>     '+(point.y).toPrecision(4)

        },
        divid = document.getElementById('myDiv'),
        newIndex = (divid.layout.annotations || []).length;
    console.log(point.pointNumber)
     // delete instead if clicked twice
    if(newIndex) {
       var foundCopy = false;
       divid.layout.annotations.forEach(function(ann, sameIndex) {
         if(ann.text === newAnnotation.text ) {
           Plotly.relayout('myDiv', 'annotations[' + sameIndex + ']', 'remove');
           foundCopy = true;
         }
       });
       if(foundCopy) return;
     }
     Plotly.relayout('myDiv', 'annotations[' + newIndex + ']', newAnnotation);
  })
  .on('plotly_clickannotation', function(event, data) {
    Plotly.relayout('myDiv', 'annotations[' + data.index + ']', 'remove');
  });
var n = 250;
var t = 12;
var x = [];
var y = [];
var z = [];
var text = [];
var arr = ["A","T","G", "C"];

for (var j = 0; j < t; j++){
  ztemp = [];
  for (var i = 0; i < n; i++) {
    x.push(i);
    y.push(j);
    ztemp.push(Math.floor(Math.random() * 10));
    text.push(arr[Math.floor(Math.random() * 4)])
  }
  z.push(ztemp)
}

var steps = [];
for (var e = 0; e < n-30; e++){
  steps.push({
      label: e,
      value: e,
      method: 'relayout',
      args: ['xaxis', {range: [-0.5 + e, 30.5 + e]}]
    })
}

data1 = {
  x: x,
  y: y,
  mode: "text",
  text: text,
  type: "scattergl",
  textfont: {
    size: 20
    }
  }
       
data2 = {
  z: z,
  type: "heatmap"
  }

sliders = [{
      active: 0,
      steps: steps
    }]

layout = {
  sliders: sliders,
  xaxis: {
    range: [-0.5, 30.5],
    showline: false,
    zeroline: false,
     showgrid: false
  },
  yaxis: {
    showline: false,
    zeroline: false,
     showgrid: false
  }  
  }

data = [data1, data2]
Plotly.newPlot('myDiv', {data:data,
                     layout:layout});