#!/usr/bin/env python # coding: utf-8 # qgrid - SlickGrid in Jupyter Notebooks # ====================================== # Qgrid is an IPython widget which uses a javascript library called SlickGrid to render pandas DataFrames within a Jupyter notebook. It was developed for use in [Quantopian's hosted research environment]( https://www.quantopian.com/research?utm_source=github&utm_medium=web&utm_campaign=qgrid-nbviewer). # ## Overview # * [SlickGrid](https://github.com/mleibman/SlickGrid) is a javascript grid which allows users to scroll, sort, # and filter hundreds of thousands of rows with extreme responsiveness. # * [Pandas](https://github.com/pydata/pandas) is a powerful data analysis / manipulation library for Python, and DataFrames are the primary way of storing and manipulating two-dimensional data in pandas. # # [Qgrid](https://github.com/quantopian/qgrid) renders pandas DataFrames as SlickGrids, which enables users to explore the entire contents of a DataFrame using intuitive sorting and filtering controls. It's designed to be used within Jupyter notebook, and it's also mostly functional when rendered by [nbviewer](http://nbviewer.ipython # .org/github/quantopian/qgrid/blob/master/qgrid_demo.ipynb). # ## Notebook installation # First, import the qgrid module as you would any other module in Python. If that doesn't work, something may have gone wrong while installing the qgrid package using pip. I would go through the package installation steps on the [GitHub page](https://github.com/quantopian/qgrid) again with a new virtualenv to make sure everything installed correctly. # In[1]: import qgrid # ##### Prepare non-python dependencies by calling [nbinstall](http://qgrid.readthedocs.org/en/latest/#qgrid.nbinstall) # This step is required because at this point all you've done to install qgrid is to call `pip install`. Pip doesn't know which folder your Jupyter notebook widgets need to get copied to (let's call this the "widgets folder"), only the Jupyter notebook process knows that. So you need to run one line of code from within the Jupyter notebook to copy qgrid to the widgets folder. This only has to be done once for a particular version of qgrid. That being said, if you're running qgrid from it's source code and making changes to it's source code, you'll need to run this line every time you make a change, or else the changes won't do anything. See our [API docs for the nbinstall function](http://qgrid.readthedocs.org/en/latest/#qgrid.nbinstall) for more details. # In[ ]: qgrid.nbinstall(overwrite=True) # copies javascript dependencies to your /nbextensions folder # ## API & Usage # API documentation is hosted on readthedocs: http://qgrid.readthedocs.org/en/latest/ # # The API documentation can also be accessed via the "?" operator in IPython. To use the "?" operator, type the name of the function followed by "?" to see the documentation for that function, like this: # ``` # qgrid.nbinstall? # qgrid.show_grid? # qgrid.set_defaults? # qgrid.set_grid_options? # # ``` # ## Example 1 - Render a DataFrame returned by Yahoo Finance # # ### 1. Create a sample DataFrame using the `get_data_yahoo` function and render it without using qgrid # In[3]: import pandas as pd import numpy as np randn = np.random.randn # Set this pandas option to prevent the grid from being too big pd.set_option('display.max_rows', 8) # Get a pandas DataFrame containing the daily prices for the S&P 500 from 1/1/2011 - 1/1/2014 from pandas_datareader.data import get_data_yahoo spy = get_data_yahoo( symbols='SPY', start=pd.Timestamp('2011-01-01'), end=pd.Timestamp('2014-01-01'), adjust_price=True, ) spy # *The table above is Jupyter notebook's default representation of the 'spy' DataFrame.* # ### 2. Render the DataFrame again, this time using qgrid # In[4]: qgrid.show_grid(spy) # *The cell above shows the same 'spy' DataFrame rendered as a qgrid. Qgrids allows you to scroll, sort, and filter hundreds of thousands of rows with extreme responsiveness. If you double click on the cells they become editable, and the edits change the values stored in the DataFrame as you would expect.* # ### 3. Now render with qgrid again, and set the `grid_options` parameter # The `show_grid` function takes a number of optional parameters to allow you to configure the behavior of the grid it generates. In the following example we use the `grid_options` parameter. # # `grid_options` takes a dict and allows you to pass any of the "grid options" listed in [SlickGrid's documentation](https://github.com/mleibman/SlickGrid/wiki/Grid-Options). In this example we make use of two of these options, `forceFitColumns` and `defaultColumnWidth`, to improve qgrid's ability to handle a large number of columns. You can read about `grid_options` and the rest of the optional parameters for the `show_grid` function in our [API documentation](http://qgrid.readthedocs.org/en/latest/#qgrid.show_grid). # # If you find yourself frequently passing the same options into `show_grid`, the `set_defaults` function may be useful to you. It allows you to set the same options that you would normally pass to `show_grid`, but through a separate function which sets the options for the lifetime of the kernel rather than for a single grid. See the [API documentation](http://qgrid.readthedocs.org/en/latest/#qgrid.set_defaults) for the `set_defaults` function for more information. # In[5]: qgrid.show_grid(spy, grid_options={'forceFitColumns': False, 'defaultColumnWidth': 200}) # *The same 'spy' DataFrame rendered as a qgrid again, this time some options tweaked. The toolbar buttons are visible, the columns are wider, and a horizontal scroll bar has appeared.* # ## Example 2 - Render a DataFrame returned by World Bank's World Development Indicators # # ### 1. Create a sample DataFrame using the `wb.download` function and render it without using qgrid # In[6]: from pandas_datareader import wb df2 = wb.download(indicator='NY.GDP.PCAP.KD', country=['all'], start=2005, end=2008) df2.columns = ['GDP per capita (constant 2005 US$)'] df2 # ### 2. Render the DataFrame again, this time using qgrid # In[7]: qgrid.show_grid(df2) # ## Example 3 - Rendering a grid by creating a QGridWidget # ### 1. Create a new sample DataFrame and render it without using qgrid # In[8]: df3 = pd.DataFrame({ 'A' : 1., 'B' : pd.Timestamp('20130102'), 'C' : pd.Series(randn(8),index=list(range(8)),dtype='float32'), 'D' : np.array([3] * 8,dtype='int32'), 'E' : pd.Categorical(["washington", "adams", "madison", "lincoln","jefferson", "hamilton", "roosevelt", "kennedy"]), 'F' : 'foo' }) df3 # ### 2. Render the DataFrame again, this time using the QGridWidget class directly # The ``show_grid`` function is just a convenience function which internally constructs an instance of QGridWidget and renders it with jupyter notebook's ``display`` function. The following code shows how to construct a QGridWidget directly, so that you can retrieve or update the DataFrame it uses internally. # In[12]: from IPython.display import display grid = qgrid.QGridWidget(df=df3) display(grid) # ### 3. Get the DataFrame back from the QGridWidget and render it without qgrid # If you make edits to the data using the grid above, they will be reflected in the DataFrame that is returned by ``grid.df``. # In[10]: grid.df # In[ ]: