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.Face
s) 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.GlyphBounds
here -
sfnt.Font.GlyphAdvance
here ie: as far asadvance
is 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).