|
| 1 | +### Creating a grid with `grid_objs` |
| 2 | + |
| 3 | +```python |
| 4 | +from plotly.grid_objs import Column, Grid |
| 5 | + |
| 6 | +column_1 = Column([1, 2, 3], 'column 1') |
| 7 | + |
| 8 | +column_2 = Column(['a', 'b', datetime.datetime.now()], 'column 2') |
| 9 | + |
| 10 | +grid = Grid(column_1, column_2) |
| 11 | + |
| 12 | +unique_url = py.grid_ops.upload(grid, filename, world_readable=True) |
| 13 | +``` |
| 14 | + |
| 15 | +### Updating grids |
| 16 | + |
| 17 | +Grids are identified with either `grid` or `grid_url`, or `filename` |
| 18 | +`filename` will be unsupported in this version |
| 19 | +```python |
| 20 | + |
| 21 | +rows = [[1, 'a'], [2, 'b']] |
| 22 | + |
| 23 | +grid = Grid(c1, c2) |
| 24 | + |
| 25 | +py.grid_ops.upload(grid, 'my file') |
| 26 | + |
| 27 | +# We recommend this call signature, since `row` gets appended to the grid |
| 28 | +py.grid_ops.append_rows(rows, grid=grid) |
| 29 | + |
| 30 | +# But, these all do the same thing |
| 31 | +py.grid_ops.append_rows(rows, grid_url="https://plot.ly/~chris/3") #shortcut |
| 32 | +py.grid_ops.append_rows(rows, filename='my file') # currently unsupported. |
| 33 | + # will do a get request behind |
| 34 | + # the scenes to get the grid_id |
| 35 | +``` |
| 36 | + |
| 37 | +Similarly for appending columns: |
| 38 | +```python |
| 39 | +from plotly.grid_objs import Column |
| 40 | + |
| 41 | +new_col = Column([1,2,3], 'new col name') |
| 42 | + |
| 43 | +# these are equivalent |
| 44 | +py.grid_ops.append_columns([new_col], grid_url='https://plot.ly/~chris/3') |
| 45 | +py.grid_ops.append_columns([new_col], filename='my file') # Currently unsupported |
| 46 | + |
| 47 | +# this, too: |
| 48 | +grid = Grid(Column([1,2,3], 'first column name')) |
| 49 | +py.grid_ops.upload(grid, 'my file') |
| 50 | + |
| 51 | +py.grid_ops.append_columns([new_col], grid=grid) # also implicitly adds new_col to grid |
| 52 | + |
| 53 | +grid[0].name # 'first column name' |
| 54 | +grid[1].name # 'new col name' |
| 55 | +``` |
| 56 | + |
| 57 | + |
| 58 | +### On overwriting and duplicate file names and deletion |
| 59 | + |
| 60 | +Overwriting currently isn't possible. For now, |
| 61 | +```python |
| 62 | +>> py.grid_ops.upload(grid, 'my grid') |
| 63 | +"PlotlyFileException: Yikes, a file already exists with this filename." |
| 64 | +"You can delete that file with:" |
| 65 | +"> py.grid_ops.delete('my grid')" |
| 66 | +"Warning: If any graphs were made from this grid, the data in those graphs" |
| 67 | +"will also be lost. If you make a new grid after you delete with the same filename, " |
| 68 | +"the new grid's URL will also be different." |
| 69 | +"That's confusing and you're probably not having a good time."" |
| 70 | + |
| 71 | +``` |
| 72 | + |
| 73 | +In the near future: |
| 74 | +```python |
| 75 | +# Updates the data, but not the column ids, of the grid. Referenced plots don't break. |
| 76 | +# Behind the scenes, this: |
| 77 | +# 1 - Makes a `GET` request to retrieve a {column_name: column_id} hash |
| 78 | +# 2 - Makes a `PUT` request to update the data of the columns |
| 79 | +>> py.grid_ops.upload('my grid') # overwrite defaults to True |
| 80 | + |
| 81 | +# Or, recieve an exception with: |
| 82 | +>> py.grid_ops.upload(grid, 'my grid', overwrite=False) |
| 83 | +"PLotlyFileException: Yikes! ..." |
| 84 | +``` |
| 85 | + |
| 86 | +Deleting: |
| 87 | + |
| 88 | +``` |
| 89 | +# throw good errors if none or more than 1 were specified |
| 90 | +py.grid_ops.delete(filename=None, grid_url=None, grid=None, grid_id=None) |
| 91 | +``` |
| 92 | + |
| 93 | +In the future, once we can delete Plots and Folders |
| 94 | + |
| 95 | +``` |
| 96 | +py.file_ops.delete(file_path=None, fid=None, url=None) |
| 97 | +``` |
| 98 | + |
| 99 | + |
| 100 | +### Appearance and Access |
| 101 | + |
| 102 | +```python |
| 103 | +>> print Column([1,2,3], 'column 1') |
| 104 | +<Column "column 1": [1, 2, 3]> |
| 105 | +``` |
| 106 | + |
| 107 | +```python |
| 108 | +>> print Grid(col1, col2) |
| 109 | +<Grid: [<Column "column 1": [1, 2, 3]>, <Column "column 2": ["a", "b", "c"]>]> |
| 110 | +``` |
| 111 | + |
| 112 | +```python |
| 113 | +>> grid = Grid(col1, col2) |
| 114 | +>> print grid[0] |
| 115 | +<Column "column 1": [1, 2, 3]> |
| 116 | +``` |
| 117 | + |
| 118 | +```python |
| 119 | +>> grid = Grid(col1, col2) |
| 120 | +>> print grid.get_column('column 1') |
| 121 | +<Column "column 1": [1, 2, 3]> |
| 122 | +``` |
| 123 | + |
| 124 | +### Creating a graph from a grid |
| 125 | + |
| 126 | +If you have the grid |
| 127 | +```python |
| 128 | +>> from plotly.grid_objs import Grid |
| 129 | +>> grid = Grid(column_1, column_2) |
| 130 | +>> grid.upload(grid, 'experimental data') |
| 131 | + |
| 132 | +>> fig_data = [Scatter(xsrc=grid[0], ysrc=grid[0])] |
| 133 | +>> print Scatter(xsrc=grid[0], ysrc=grid[1]) |
| 134 | +[{"xsrc": "chris/8:3dkb", "ysrc": "chris/8:cbk8", "type": "scatter"}] |
| 135 | +>> py.plot(fig_data) |
| 136 | + |
| 137 | +>> Scatter(x=[1,2,3], y=[2,1,2]) |
| 138 | +"High five!" |
| 139 | +>> Scatter(xsrc=[1,2,3], ysrc=[2,1,2]) |
| 140 | +"PlotlyTypeException: xrc and ysrc must be type string or plotly.grid_obj.Column" |
| 141 | +>> Scatter(xsrc=Column('myCol', [1,2,3]), ysrc=Column('otherCol', [2,1,2])) |
| 142 | +"PlotlyFileException: you must upload a grid before you can reference it in plots" |
| 143 | +>> Scatter(xsrc=localGrid[0], ysrc=localGrid[1]) |
| 144 | +"PlotlyFileException: you must upload a grid before you can reference it in plots" |
| 145 | +>> Scatter(x=grid[0], y=grid[1]) |
| 146 | +"PlotlyTypeException: Yikes, column objects aren't currently supported here." |
| 147 | +"x must be an array of strings, numbers, or datetimes." |
| 148 | +>> print Scatter(xsrc=grid[0], yscr=grid[1]) |
| 149 | +{"xsrc": "chris/3:3dfbk", "ysrc": "chris/3:dk3c"} |
| 150 | +``` |
| 151 | + |
| 152 | +Otherwise, download the grid (Not currently supported) |
| 153 | +``` |
| 154 | +>> grid = grid_ops.get(filename=None, grid_id=None, grid_url=None) |
| 155 | +``` |
| 156 | + |
| 157 | +(Download should use same endpoint as `grid_url.json`, e.g. [https://plot.ly/~chris/142.json](https://plot.ly/~chris/142.json)) |
| 158 | + |
| 159 | +### Errors |
| 160 | +```python |
| 161 | +>> grid = Grid(column_1, column_2) |
| 162 | +>> trace = Scatter(x=grid[0], y=grid[1]) |
| 163 | +"PlotlyGridException: Grid must be uploaded to Plotly before figures can be created." |
| 164 | +"Call `py.grid_ops.upload(grid)`" |
| 165 | +``` |
| 166 | + |
| 167 | +```python |
| 168 | +>> col1 = Column([], 'my column name') |
| 169 | +>> col2 = Column([], 'my column name') |
| 170 | +>> Grid(col1, col2) |
| 171 | +"PlotlyGridException: Grid can't have duplicate column names" |
| 172 | +``` |
| 173 | + |
| 174 | +```python |
| 175 | +>> py.grid_ops.append_row(Row({'column 1': 1}), grid=grid) |
| 176 | +"PlotlyGridException: Missing column entries, partial row update is not supported." |
| 177 | +"Supply data for 'column 2' and try again." |
| 178 | +``` |
| 179 | + |
| 180 | +Type checking boiler plate |
| 181 | +```python |
| 182 | +>> Column({'a': 'b'}, 'col1') |
| 183 | +"PlotlyColumnException: Data argument must be an array of numbers, strings, Nones, or datetimes" |
| 184 | +``` |
| 185 | + |
| 186 | +```python |
| 187 | +>> Column([{'a': 'b'}], 'col1') |
| 188 | +"PlotlyColumnException: Data values must be an array string, a number, Nones, or a datetime" |
| 189 | +``` |
| 190 | + |
| 191 | +### Exceptions from Requests |
| 192 | +A `PlotlyRequestError` that prints a useful error message from the server: |
| 193 | +1. Print `response.detail` if provided (Plotly error message) |
| 194 | +2. Otherwise, print `response.body` if the response is plain-text |
| 195 | +3. Otherwise, print the original `requests.expceptions.HTTPError` error message. |
| 196 | + |
| 197 | +Also, store the status code. |
| 198 | + |
| 199 | + |
| 200 | +### Adding metadata to grids |
| 201 | + |
| 202 | +```python |
| 203 | +c1 = Column('first column', [1, 2, 3, 4]) |
| 204 | +grid = Grid([c1]) |
| 205 | +meta = {"settings":{"scope1":{"model":"Unicorn Finder","voltage":4}}} |
| 206 | +py.grid_ops.upload( |
| 207 | + grid, |
| 208 | + unique_filename, |
| 209 | + meta=meta, |
| 210 | + auto_open=False) |
| 211 | +``` |
| 212 | + |
| 213 | +```python |
| 214 | +# First, create a grid |
| 215 | +c1 = Column('first column', [1, 2, 3, 4]) |
| 216 | +grid = Grid([c1]) |
| 217 | +grid_url = py.grid_ops.upload(grid, unique_filename, auto_open=False) |
| 218 | + |
| 219 | +# Add some meta data to that grid |
| 220 | +meta = {"settings": {"scope1": {"model": "Unicorn Finder", "voltage": 4}}} |
| 221 | +meta_url = py.meta_ops.upload( |
| 222 | + meta, |
| 223 | + grid_url=grid_url) |
| 224 | +``` |
| 225 | + |
| 226 | +### Plotly File system |
| 227 | + |
| 228 | +```python |
| 229 | + |
| 230 | +>> py.file_ops.mkdirs('new folder in root') |
| 231 | + |
| 232 | +>> py.file_ops.mkdirs('make/each/of/these/folders') |
| 233 | +``` |
| 234 | + |
| 235 | +Note that this is like `mkdir -p`. `mkdirs` is a Java convention. |
| 236 | +We could also use our own, like: |
| 237 | + |
| 238 | +- `py.file_ops.create_folders('new/folders')` |
| 239 | +- `py.file_ops.new_folders('new/folders')` |
| 240 | + |
| 241 | +These commands will: |
| 242 | +- return status codes: `200` if nothing created, `201` if created |
| 243 | +- raise exception if a file or folder already exists with that path |
| 244 | + |
| 245 | + |
| 246 | +In the future, once we can delete Plots and Folders |
| 247 | + |
| 248 | +``` |
| 249 | +py.file_ops.delete(file_path=None, fid=None, url=None) |
| 250 | +``` |
| 251 | + |
| 252 | +Or, if we want to keep unix convention (do we?) |
| 253 | +``` |
| 254 | +py.file_ops.rm(file_path=None, fid=None, url=None) |
| 255 | +``` |
0 commit comments