'Initialize a grid with an iterable of `plotly.grid_objs.Column`
objects or a json/dict describing a grid. See second usage example
below for the necessary structure of the dict.
:param (str|bool) fid: should not be accessible to users. Default
is \'None\' but if a grid is retrieved via `py.get_grid()` then the
retrieved grid response will contain the fid which will be
necessary to set `self.id` and `self._columns.id` below.
Example from iterable of columns:
column_1 = Column([1, 2, 3], \'time\')
column_2 = Column([4, 2, 5], \'voltage\')
grid = Grid([column_1, column_2])
Example from json grid
grid_json = {
\'cols\': {
\'time\': {\'data\': [1, 2, 3], \'order\': 0, \'uid\': \'4cd7fc\'},
\'voltage\': {\'data\': [4, 2, 5], \'order\': 1, \'uid\': u\'2744be\'}
grid = Grid(grid_json)'

def __init__(self, columns_or_json, fid=None):

    if (pd and isinstance(columns_or_json, pd.DataFrame)):
        duplicate_name = utils.get_first_duplicate(columns_or_json.columns)
        if duplicate_name:
            err = exceptions.NON_UNIQUE_COLUMN_MESSAGE.format(duplicate_name)
            raise exceptions.InputError(err)
        all_columns = []
        for name in columns_or_json.columns:
            all_columns.append(Column(columns_or_json[name].tolist(), name))
        self._columns = all_columns
        self.id = ''
    elif isinstance(columns_or_json, dict):
        if (fid is None):
            raise exceptions.PlotlyError("If    you    are    manually    converting    a    raw    json/dict    grid    into    a    Grid    instance,    you    must    ensure    that    'fid'    is    set    to    your    file    ID.    This    looks    like    'username:187'.")
        self.id = fid
        if ('cols' not in columns_or_json):
            raise exceptions.PlotlyError("'cols'    must    be    a    root    key    in    your    json    grid.")
        grid_col_keys = ['data', 'order', 'uid']
        for column_name in columns_or_json['cols']:
            for key in grid_col_keys:
                if (key not in columns_or_json['cols'][column_name]):
                    raise exceptions.PlotlyError("Each    column    name    of    your    dictionary    must    have    'data',    'order'    and    'uid'    as    keys.")
        all_orders = []
        for column_name in columns_or_json['cols'].keys():
            all_orders.append(columns_or_json['cols'][column_name]['order'])
        all_orders.sort()
        ordered_columns = []
        for order in all_orders:
            for column_name in columns_or_json['cols'].keys():
                if (columns_or_json['cols'][column_name]['order'] == order):
                    break
            ordered_columns.append(Column(columns_or_json['cols'][column_name]['data'], column_name))
        self._columns = ordered_columns
        for column in self:
            column.id = ((self.id + ':') + columns_or_json['cols'][column.name]['uid'])
    else:
        column_names = [column.name for column in columns_or_json]
        duplicate_name = utils.get_first_duplicate(column_names)
        if duplicate_name:
            err = exceptions.NON_UNIQUE_COLUMN_MESSAGE.format(duplicate_name)
            raise exceptions.InputError(err)
        self._columns = list(columns_or_json)
        self.id = ''
