Vindaar / ggplotnim

A port of ggplot2 for Nim
https://vindaar.github.io/ggplotnim
MIT License
176 stars 15 forks source link

How to set margins in a plot? #89

Closed hffqyd closed 4 years ago

hffqyd commented 4 years ago

I encountered a problem that when I had a very long label in a plot, it exceeded the figure. Take the example below:

import ggplotnim, sequtils, seqmath

let
  pos = [1,2,3,1,2,3]
  name = ["a very long long label", "a very long long label", "a very long long label", "b", "b", "b"]
  n = [0, 1, 4, 4, 2, 3]
  df = seqsToDf(pos, name, n)

ggplot(df, aes("pos", "name")) + 
geom_tile(aes(fill = "n")) + 
geom_text(aes(text = "n"), size = some(25.0)) + 
scale_x_discrete() + 
scale_y_discrete() + 
ggsave("gg.pdf")

The label of "a very long long label" would exceed the left edge.

I found a solution in "recipes.org" using ggcreate(), initViewport() to set extra space to the left and embed the figure in the right.

import ggplotnim, sequtils, seqmath, tables, chroma, ginger

let
  pos = [1,2,3,1,2,3]
  name = ["a very long long label", "a very long long label", "a very long long label", "b", "b", "b"]
  n = [0, 1, 4, 4, 2, 3]
  df = seqsToDf(pos, name, n)

let ht = ggcreate(
ggplot(df, aes("pos", "name")) + 
geom_tile(aes(fill = "n")) + 
geom_text(aes(text = "n"), size = some(25.0)) + 
scale_x_discrete() + 
legendPosition(1.0, 1.0), 
width = 640, height = 480)

var plt = initViewport(wImg = 700, hImg = 480)
plt.layout(cols = 2, rows = 1, colwidths = @[quant(0.1, ukRelative), quant(0.0, ukRelative)], rowheights = @[quant(0.0, ukRelative)])
plt.embedAt(1, ht.view)
plt.draw("gg.pdf")

The code worked. But I'm wondering if there is a more convenient way to set margin to avoid long label exceeding? Thanks for kindly help!

Vindaar commented 4 years ago

This is another case of something not being exposed just yet. I'll add that soon.

The layout is currently hardcoded depending on whether a legend is required or not here: https://github.com/Vindaar/ggplotnim/blob/master/src/ggplotnim.nim#L1382-L1432

This will simply be something that can be set by the used Theme by extending it: https://github.com/Vindaar/ggplotnim/blob/master/src/ggplotnim/ggplot_types.nim#L232-L267 and handing that to the layouting procs above.

hffqyd commented 4 years ago

Thanks for you reply. Waiting for your completion and I'll test for it.

Vindaar commented 4 years ago

Something I forgot to mention: You can also always rotate the labels for a better fit using using the rotate argument to xlab/ylab as done here:

https://github.com/Vindaar/ggplotnim/blob/master/recipes.org#bar-plot-with-many-elements-rotate-labels

hffqyd commented 4 years ago

OK, thank you. I'll try it.

Vindaar commented 4 years ago

Finally got around to implementing this. See here:

https://github.com/Vindaar/ggplotnim/blob/allowCustomMargins/recipes.org#customizing-the-margins-around-a-plot

edit: feel free to reopen, if this doesn't work as you expect.