1""" 2Mapping of the R library "grid" for graphics. 3 4The R library provides a low-level coordinate 5system and graphic primitives to built visualizations. 6 7 8""" 9 10import rpy2.robjects as robjects 11import rpy2.robjects.conversion as conversion 12from rpy2.rlike.container import OrdDict 13from rpy2.robjects.packages import importr, WeakPackage 14 15NULL = robjects.NULL 16 17grid = importr('grid') 18 19grid = WeakPackage(grid._env, 20 grid.__rname__, 21 translation=grid._translation, 22 exported_names=grid._exported_names, 23 on_conflict="warn", 24 version=grid.__version__, 25 symbol_r2python=grid._symbol_r2python, 26 symbol_resolve=grid._symbol_resolve) 27 28grid_env = robjects.baseenv['as.environment']('package:grid') 29 30 31layout = grid.grid_layout 32newpage = grid.grid_newpage 33grill = grid.grid_grill 34edit = grid.grid_edit 35get = grid.grid_get 36remove = grid.grid_remove 37add = grid.grid_add 38xaxis = grid.grid_xaxis 39yaxis = grid.grid_yaxis 40 41 42class Unit(robjects.RObject): 43 """ Vector of unit values (as in R's grid package) """ 44 _unit = grid_env['unit'] 45 46 @classmethod 47 def unit(cls, *args, **kwargs): 48 """ Constructor (uses the R function grid::unit())""" 49 res = cls._unit(*args, **kwargs) 50 return res 51 52 53unit = Unit.unit 54 55 56class Gpar(robjects.RObject): 57 """ Graphical parameters """ 58 _gpar = grid_env['gpar'] 59 _get_gpar = grid_env['get.gpar'] 60 61 @classmethod 62 def gpar(cls, *args, **kwargs): 63 """ Constructor (uses the R function grid::gpar())""" 64 res = cls._gpar(*args, **kwargs) 65 return res 66 67 def get(self, names=None): 68 return self._get_gpar(names) 69 70 71gpar = Gpar.gpar 72 73 74class Grob(robjects.RObject): 75 """ Graphical object """ 76 _grob = grid_env['grob'] 77 _draw = grid_env['grid.draw'] 78 79 def __init__(self, *args, **kwargs): 80 od = OrdDict() 81 for item in args: 82 od[None] = conversion.py2rpy(item) 83 for k, v in kwargs.items(): 84 od[k] = conversion.py2rpy(v) 85 res = self._constructor.rcall(tuple(od.items()), robjects.globalenv) 86 super().__init__(res.__sexp__) 87 88 @classmethod 89 def grob(cls, **kwargs): 90 """ Constructor (uses the R function grid::grob())""" 91 res = cls._grob(**kwargs) 92 return res 93 94 def draw(self, recording=True): 95 """ Draw a graphical object (calling the R function 96 grid::grid.raw())""" 97 self._draw(self, recording=recording) 98 99 100grob = Grob.grob 101 102 103class Rect(Grob): 104 _constructor = grid_env['rectGrob'] 105 106 107rect = Rect 108 109 110class Lines(Grob): 111 _constructor = grid_env['linesGrob'] 112 113 114lines = Lines 115 116 117class Circle(Grob): 118 _constructor = grid_env['circleGrob'] 119 120 121circle = Circle 122 123 124class Points(Grob): 125 _constructor = grid_env['pointsGrob'] 126 127 128points = Points 129 130 131class Text(Grob): 132 _constructor = grid_env['textGrob'] 133 134 135text = Text 136 137 138class GTree(Grob): 139 """ gTree """ 140 _gtree = grid_env['gTree'] 141 _grobtree = grid_env['grobTree'] 142 143 @classmethod 144 def gtree(cls, **kwargs): 145 """ Constructor (uses the R function grid::gTree())""" 146 res = cls._gtree(**kwargs) 147 return res 148 149 @classmethod 150 def grobtree(cls, **kwargs): 151 """ Constructor (uses the R function grid::grobTree())""" 152 res = cls._grobtree(**kwargs) 153 return res 154 155 156class Axis(GTree): 157 pass 158 159 160class XAxis(Axis): 161 _xaxis = xaxis 162 _xaxisgrob = grid.xaxisGrob 163 164 @classmethod 165 def xaxis(cls, **kwargs): 166 """ Constructor (uses the R function grid::xaxis())""" 167 res = cls._xaxis(**kwargs) 168 return res 169 170 @classmethod 171 def xaxisgrob(cls, **kwargs): 172 """ Constructor (uses the R function grid::xaxisgrob())""" 173 res = cls._xaxisgrob(**kwargs) 174 return res 175 176 177class YAxis(Axis): 178 _yaxis = yaxis 179 _yaxisgrob = grid.yaxisGrob 180 181 @classmethod 182 def yaxis(cls, **kwargs): 183 """ Constructor (uses the R function grid::yaxis())""" 184 res = cls._yaxis(**kwargs) 185 return res 186 187 @classmethod 188 def yaxisgrob(cls, **kwargs): 189 """ Constructor (uses the R function grid::yaxisgrob())""" 190 res = cls._yaxisgrob(**kwargs) 191 return res 192 193 194class Viewport(robjects.RObject): 195 """ Drawing context. 196 Viewports can be thought of as nodes in a scene graph. """ 197 198 _pushviewport = grid_env['pushViewport'] 199 _popviewport = grid_env['popViewport'] 200 _current = grid_env['current.viewport'] 201 _plotviewport = grid_env['plotViewport'] 202 _downviewport = grid_env['downViewport'] 203 _seek = grid_env['seekViewport'] 204 _upviewport = grid_env['upViewport'] 205 _viewport = grid_env['viewport'] 206 207 def push(self, recording=True): 208 self._pushviewport(self, recording=recording) 209 210 @classmethod 211 def pop(cls, n): 212 """ Pop n viewports from the stack. """ 213 cls._popviewport(n) 214 215 @classmethod 216 def current(cls): 217 """ Return the current viewport in the stack. """ 218 cls._current() 219 220 @classmethod 221 def default(cls, **kwargs): 222 cls._plotviewport(**kwargs) 223 224 @classmethod 225 def down(cls, name, strict=False, recording=True): 226 """ Return the number of Viewports it went down """ 227 cls._downviewport(name, strict=strict, recording=recording) 228 229 @classmethod 230 def seek(cls, name, recording=True): 231 """ Seek and return a Viewport given its name """ 232 cls._seek(name, recording=recording) 233 234 @classmethod 235 def up(cls, n, recording=True): 236 """ Go up n viewports """ 237 cls._downviewport(n, recording=recording) 238 239 @classmethod 240 def viewport(cls, **kwargs): 241 """ Constructor: create a Viewport """ 242 res = cls._viewport(**kwargs) 243 res = cls(res) 244 return res 245 246 247viewport = Viewport.viewport 248 249_grid_dict = { 250 'gpar': Gpar, 251 'grob': Grob, 252 'gTree': GTree, 253 'unit': Unit, 254 'xaxis': XAxis, 255 'yaxis': YAxis, 256 'viewport': Viewport 257} 258 259original_py2rpy = None 260original_rpy2py = None 261 262 263def grid_rpy2py(robj): 264 265 pyobj = original_rpy2py(robj) 266 267 if not isinstance(pyobj, robjects.RS4): 268 rcls = pyobj.rclass 269 if rcls is NULL: 270 rcls = (None, ) 271 try: 272 cls = _grid_dict[rcls[0]] 273 pyobj = cls(pyobj) 274 except KeyError: 275 pass 276 277 return pyobj 278 279 280def activate(): 281 global original_py2rpy, original_rpy2py 282 283 # If module is already activated, there is nothing to do 284 if original_py2rpy: 285 return 286 287 original_py2rpy = conversion.py2rpy 288 original_rpy2py = conversion.rpy2py 289 290 conversion.rpy2py = grid_rpy2py 291 292 293def deactivate(): 294 global original_py2rpy, original_rpy2py 295 296 # If module has never been activated or already deactivated, 297 # there is nothing to do 298 if not original_py2rpy: 299 return 300 301 conversion.py2rpy = original_py2rpy 302 conversion.rpy2py = original_rpy2py 303 original_py2rpy = original_rpy2py = None 304