Changing axis label size while using Plot

Hello,

How would I go about changing the font size of the axis labels in a Plot like so:

area = Plot.areaY(datasort, {
  x: "Date",
  y: "Count",
  fill: "Zone",
  order: "sum",
  reverse: true,
  inset: 0,
  title: "Zone"
}).plot({
  width,
  height: 900,
})

I know you can change the font size of Plot.text with fontSize:30 but this only works for marks and not the x and y axis labels.

Is there a way to do this without changing the entire html with something like:

html `<style>
text {
font-size: 22px;
}
</style>`

As that doesn’t work in my situation…

Plot 0.3 introduces a className option on top of the style option; hopefully this is enough to change whatever is necessary?

So I set a className in the Plot like so:

area = Plot.areaY(datasort, {
  x: "Date",
  y: "Count",
  className: "disco",
  fill: "Zone",
  order: "sum",
  reverse: true,
  inset: 0,
  title: "Zone"
}).plot({
  width,
  height: 900,
  style: {
    fontSize: 30,
  },
})

and then I use

html `<disco><style> text { font-size: 22px; } </style></disco>`

to change only the specific SVG element with that className?

So I couldn’t figure out how to use the className properly to set the font-size…

But I did figure out that if I just directly alter the attribute value with:

area.setAttribute("font-size", 30);

It will change the x and y text sizes.

Unfortunately, these attribute settings don’t carry over when you import the cell into another notebook so this doesn’t work for my intended uses.

Does anyone know a way to import the set attributes with the cell? Or a way to set the attribute so that it is imported as set?

If you call area.setAttribute in a different cell, then you’ll need to name, import, and execute that into your other notebook as well for it to take effect. Alternatively, you could bundle it all into a single cell. Something like

{
  let area = ...
  area.setAttribute(“font-size”, 30);
  return area
}

Of course, that will set the global font-size for the whole figure. You might also inspect the SVG and use CSS selectors to target the text more specifically. Something like so:

{
  let p = Plot.plot({
    marks: [Plot.line(d3.range(0, 20, 0.1).map((t) => [t, Math.sin(t)]))],
    x: { label: "t" },
    y: { label: "y" },
    margin: 60
  });

  let sel = d3.select(p).selectAll("svg > g > text").style("font-size", "20px");

  return p;
}

Of course, that will be quite fragile and would depend on the exact structure of your output. Proper class names would be ideal.

@Fil As far as I can tell, the className option only applies at the top level, not to marks, axes, and such.

1 Like

Yes. There is an older proposal to extend it to each of the marks and axes here: className option for plot, facets, axes and marks by Fil · Pull Request #253 · observablehq/plot · GitHub

1 Like

any new way to achieve this?

Yes, there is now a full fledged axis mark that allows you to format the text in all kinds of ways.

3 Likes

You can use the top-level style option to set the font size for the entire plot, including axis ticks and labels. For example:

Plot.plot({
  y: {label: "↑ y"},
  style: {fontSize: "16px"},
  marks: [Plot.lineX(d3.range(0, 20, 0.1), {y: Math.sin})]
})

Or equivalently:

Plot.plot({
  y: {label: "↑ y"},
  style: "font-size: 16px;",
  marks: [Plot.lineX(d3.range(0, 20, 0.1), {y: Math.sin})]
})

If you only want to affect the axes and not other marks, you can use the fontSize option on the axis marks, as @mcmcclur suggested.

Plot.plot({
  marks: [
    Plot.axisX({fontSize: 16}),
    Plot.axisY({fontSize: 16, label: "↑ y"}),
    Plot.lineX(d3.range(0, 20, 0.1), {y: Math.sin})
  ]
})
1 Like