ipysheet is a jupyter interactive widget library which provides a spreadsheet widget to the Jupyter notebook.
Installation:
conda install -c conda-forge ipysheet
ipysheet provides ways to create a sheet with interactive cells and cell-ranges:
from ipysheet import sheet, cell
s = sheet(rows=3, columns=4)
cell1 = cell(0, 0, 'Hello')
cell2 = cell(2, 0, 'World')
cell_value = cell(2,2, 42.)
s
cell1.value = 'Hi'
You can easily load your data from dataframes or arrays using the from_dataframe
and from_array
helper functions. It returns a spreadsheet containing cell-ranges with your data.
You can also use the to_dataframe
and to_array
to export your data back to Pandas/NumPy datastructures once your done interacting with it.
import numpy as np
import pandas as pd
from ipysheet import from_dataframe
number_columns = 26
dates = pd.date_range('20130101', periods=6)
df = pd.DataFrame(np.random.randn(6, number_columns), index=dates, columns=list(chr(ord('A') + i) for i in range(number_columns)))
s = from_dataframe(df)
s
The same way you can link
two widget values together, nothing stops you from linking an entire cell-range to an interactive bplot.
import numpy as np
from traitlets import link
from ipywidgets import HBox
import bqplot.pyplot as plt
from ipysheet import sheet, cell, column
size = 18
scale = 100.
np.random.seed(0)
x_data = np.arange(size)
y_data = np.cumsum(np.random.randn(size) * scale)
fig = plt.figure()
axes_options = {'x': {'label': 'Date', 'tick_format': '%m/%d'},
'y': {'label': 'Price', 'tick_format': '0.0f'}}
scatt = plt.scatter(x_data, y_data, colors=['red'], stroke='black')
fig.layout.width = '70%'
s = sheet(rows=size, columns=2)
x_column = column(0, x_data)
y_column = column(1, y_data)
link((scatt, 'x'), (x_column, 'value'))
link((scatt, 'y'), (y_column, 'value'))
HBox((fig, s))
The calculation
decorator allows you to define a cell as being the result of an operation depending on other cells. It will listen for changes on the cell dependencies, and update it dynamically.
import ipywidgets as widgets
from ipysheet import calculation
s = sheet(rows=3, columns=2, column_headers=False, row_headers=False)
cell_a = cell(0, 1, 1, label_left='a')
cell_b = cell(1, 1, 2, label_left='b')
cell_sum = cell(2, 1, 3, label_left='sum', read_only=True)
# create a slider linked to cell a
slider = widgets.FloatSlider(min=-10, max=10, description='a')
widgets.jslink((cell_a, 'value'), (slider, 'value'))
@calculation(inputs=[cell_a, cell_b], output=cell_sum)
def calculate(a, b):
return a + b
widgets.VBox([s, slider])
Custom renderers allows you to change the CSS of the cells (e.g. text color, background color) depending on the cell value. Whenever a custom renderer is created, it is then available for any cell, and you can specify which renderer a cell is using when creating it.
Here we create a renderer_negative
function which will color the cells in orange if values are negative.
from ipysheet import renderer
def renderer_negative(value):
return {
'backgroundColor': 'orange' if value < 0 else ''
}
renderer(code=renderer_negative, name='negative_transpiled');
import random
from ipysheet import cell_range
s = sheet(rows=3, columns=4)
data = [[random.randint(-10, 10) for j in range(4)] for j in range(3)]
cell_range(data, renderer='negative_transpiled')
s
from ipywidgets import FloatSlider
from ipysheet import column
s = sheet()
column1 = column(0, [FloatSlider() for _ in range(5)])
column2 = column(1, [1.] * 5)
s
and export to a dataframe:
from ipysheet import to_dataframe
to_dataframe(s)