plot
plot copied to clipboard
Padding below X axis?
I've added custom labels to my X axis but the text is getting cut off (the bottom half of the "y" in "May" isn't visible). Is there a way to add padding to the bottom of the graph?
You can use draw.Crop: https://godoc.org/github.com/gonum/plot/vg/draw#Crop.
However, if this is happening it is probably a bug so if you are willing to submit an example that reproduces the problem that would be appreciated.
Thanks!
I will put together an example. What information would you need?
Attaching an example of a graph.

We'd need the code that generated it too.
Just ran into this myself. Taking the bar charts example and changing the last NominalX name to "Twenty" produces:

This is with gonum.org/v1/plot v0.8.0 in go.mod.
Will see if I can fix it up with draw.Crop.
Thanks. I'll have a look at this soon.
It looks to me like the glyphboxes are not being drawn on the tick labels in the tests either. They should be.
I think this fixes the issue.
diff --git a/axis.go b/axis.go
index 1190ae5..1daf3d9 100644
--- a/axis.go
+++ b/axis.go
@@ -270,12 +270,13 @@ func (a horizontalAxis) draw(c draw.Canvas) {
marks := a.Tick.Marker.Ticks(a.Min, a.Max)
ticklabelheight := tickLabelHeight(a.Tick.Label, marks)
+ descent := a.Tick.Label.Font.Extents().Descent
for _, t := range marks {
x := c.X(a.Norm(t.Value))
if !c.ContainsX(x) || t.IsMinor() {
continue
}
- c.FillText(a.Tick.Label, vg.Point{X: x, Y: y + ticklabelheight}, t.Label)
+ c.FillText(a.Tick.Label, vg.Point{X: x, Y: y + ticklabelheight - descent}, t.Label)
}
if len(marks) > 0 {
diff --git a/vg/draw/text.go b/vg/draw/text.go
index 35b6699..e19ff3e 100644
--- a/vg/draw/text.go
+++ b/vg/draw/text.go
@@ -74,7 +74,7 @@ func (sty TextStyle) Height(txt string) vg.Length {
return vg.Length(0)
}
e := sty.Font.Extents()
- return e.Height*vg.Length(nl-1) + e.Ascent
+ return e.Height*vg.Length(nl-1) + e.Ascent - e.Descent
}
// Rectangle returns a rectangle giving the bounds of
A number of tests in vg/... don't update with the -regen flag.
No, it's more complicated than that; the wiring of descents into font consideration is quite ad hoc.
Thank you!
@danp Thanks for following up with a reproducer; that's what go this fixed.
@kortschak Some characters (such as ÀÉÈÎÙÔ) is also cut off in title and y axis label.

Thanks @wcshds. Maybe we should grow the bounding box a little.
@sbinet WDYT?
apologies for dropping this on the floor. I'll have a look.
ok, so the bounding box is indeed completely missing the accents:

asking on the #ui-text-rendering channel, Egon reminded me of the x/image/font.BoundString function that does what we want (and removing code from gonum to replace it with code from the almost-stdlib is great).
but there are discrepancies.
the code in gonum/plot - which more or less does what font.BoundString does - returns twice the width of font.BoundString:
https://go.dev/play/p/_hvN0Lw5YJ6
the scale parameter of opentype.Face (font.BoundString operates on font.Faces) is: Int26_6(0.5 + (fntSize * imgDPI * 64)/72)) = 1024 (with fntSize=12 and imgDPI=96)
the pixelsPerEm parameter passed to sfnt.Font.GlyphAdvance (in doGonumWidth) equals to 2048. and this value is taken straight from sfnt.Font.UnitsPerEm()
font.BoundString just uses sfnt.Font.GlyphBounds (whose code is like sfnt.Font.GlyphAdvance as far as advance is concerned).
so... clearly there is a logical flaw somewhere. but I am stuck.
Do you want something instead like this https://go.dev/play/p/GTsNZ7P8brW?
The font.Face.GlyphBounds and sfnt.Font.GlyphAdvance look like they have different understanding of advance.
ok... so I gave up on trying to understand where exactly the difference is coming from.
sfnt.Font.GlyphBoundsheresfnt.Font.GlyphAdvancehere ie: as far asadvanceis concerned, they look the same to me.
anyways. dropping the use of plot/font.Face.Extents() for the height, and using instead x/image/font.BoundString, I get the following image (using this new scheme only for the Ôag and Oag labels (bottom-left quarter)):

using that scheme for all strings:

ie: probably have to do with some impedance mismatch between code that uses plot/font.FaceExtents directly to get the height of the box and code that uses plot/text.Handler.Box.
I'll probably have to modify the plot/text.Handler interface, namely that Box method that needs to take an additional parameter (the DPI).
I must say, I am also considering just switching to go-text/typesetting and its shaping.Shaper interface.
this quite large dependency is what Gio and Fyne are using for text typesetting. (and it's still being maintained, while x/image/font is less so).