1

I want to figure out how to build complex curved lines/polygons in R. We can easily draw a simple bezier line, e.g.

require(grid)
x <- c(0.25, 0.25, 0.75, 0.75)
y <- c(0.25, 0.75, 0.75, 0.25)
grid.newpage()
grid.bezier(x, y)

enter image description here

This method seems scale-constrained to 0-1 in both axes, and I'm not sure how to build beziers in a custom scale. I'm also unclear how R can bind these bezier objects together into polylines and ultimately polygons. If anyone can provide a minimal example I'd be very grateful. But alternatively a point in the right direction of documentation would greatly help, as I've not found a workflow so far. Thanks in advance.

geotheory
  • 22,624
  • 29
  • 119
  • 196
  • Hi @geotheory! What types of curves are you drawing? What sort of relationships are there? Any dependent packages? In your example, you used `grid`. How important is that? – Myles Baker Oct 14 '14 at 18:25
  • 1
    Plotting functions using grid typically do have a range of 0-1 npc which is the default coordinate scale. Look up `?grid::unit` – IRTFM Oct 14 '14 at 21:07
  • @myles-baker I'm just looking to develop slightly more elegant graphs. Doesn't have to be grid if there's an easier way..? – geotheory Oct 15 '14 at 10:00
  • @geotheory If you could explain what you're trying to model / plot it would be helpful. `grid` is a low-level plotting library and a higher-level plotting library, like `ggplot2` or `matplot` may be more appropriate. If you want really elegant graphs, the value-proposition of a high-level library is huge. – Myles Baker Oct 15 '14 at 13:44
  • Yes I use ggplot but it can't deliver in this case, a [longitudinal allivual plot](http://stackoverflow.com/questions/8222356/how-to-generate-a-graph-diagram-like-google-analyticss-visitor-flow). Ggplot's stacked area plot comes close but ranks are fixed and lines straight. The [alluvial package](http://www.r-bloggers.com/alluvial-diagrams/) also can't handle longitudinal data as far as I can tell. So I'm trying to figure out how much work to build a function myself.. – geotheory Oct 15 '14 at 14:03
  • Ok, that's fair. I have never created alluvial plots from scratch and I'm sure it's non-trivial. I followed this blog post when I created alluvial plots using R in the past: http://www.r-bloggers.com/alluvial-diagrams/ – Myles Baker Oct 15 '14 at 14:59

2 Answers2

1

As far as I understand grid.bezier you will have to chain individuals segments. This can be done via the id argument, but see also ?grig.bezier.

You can adjust the scale through viewports and the xscale and yscale.

library(grid)
x <- c(0.2, 0.2, 0.7, 0.4, 0.2, 0.2, 0.4, 0.4)
y <- c(0.2, 0.4, 0.7, 0.2, 0.2, 0, 0, 0.2)

grid.newpage()
grid.bezier(x, y, id=rep(1:2, each=4))

grid.newpage()
pushViewport(plotViewport(xscale=c(0, 10), yscale=c(0, 100)))
grid.xaxis()
grid.yaxis()

x <- x * 10
y <- y * 50

grid.bezier(x, y, id=rep(1:2, each=4), default.units="native")

Note that I used dataViewport which is just a convenience function wrapping viewport.

johannes
  • 14,043
  • 5
  • 40
  • 51
  • This is useful thanks. How do you fill the resulting object, e.g. such as.. `x<-c(.2,.6,.4,.8); y<-c(.2,.2,.5,.5); grid.newpage(); pushViewport(plotViewport(xscale=c(0,1), yscale=c(0,1))); grid.xaxis(); grid.yaxis(); grid.bezier(x,y); grid.bezier(x,y+.3); grid.segments(.2,.2,.2,.5); grid.segments(.8,.5,.8,.8)` – geotheory Oct 15 '14 at 11:12
-1

If you have the parametrization 'Y' of the curve you want to draw, you could just

t <- c(1:1000)*0.001
plot(t,Y(t))    

or something like that.

jsdev
  • 9
  • 2