Search code examples
pythonpython-3.xpipjupyter-notebookpackage

Hide imports within another package python


Problem

I use Jupyter a lot, and while using jupyter i have the same list of imports that are long and cumbersome, something like:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from IPython.core.display import display, HTML
from ipywidgets import interact, IntSlider
from IPython.display import display

pd.options.display.max_columns = 35
pd.options.display.max_rows = 300

plt.rcParams['figure.figsize'] = [12, 8]
plt.rcParams['figure.dpi'] = 170 # 200 e.g. is really fine, but slower

import IPython.display as ipd
plt.ion()

display(HTML("<style>.container { width:95% !important; }</style>"))


def plot_frozen(df, num_rows=30, num_columns=30, step_rows=1,
                  step_columns=1):
    """
    Freeze the headers (column and index names) of a Pandas DataFrame. A widget
    enables to slide through the rows and columns.

    Parameters
    ----------
    df : Pandas DataFrame
        DataFrame to display
    num_rows : int, optional
        Number of rows to display
    num_columns : int, optional
        Number of columns to display
    step_rows : int, optional
        Step in the rows
    step_columns : int, optional
        Step in the columns

    Returns
    -------
    Displays the DataFrame with the widget
    """
    @interact(last_row=IntSlider(min=min(num_rows, df.shape[0]),
                                 max=df.shape[0],
                                 step=step_rows,
                                 description='rows',
                                 readout=False,
                                 disabled=False,
                                 continuous_update=True,
                                 orientation='horizontal',
                                 slider_color='purple'),
              last_column=IntSlider(min=min(num_columns, df.shape[1]),
                                    max=df.shape[1],
                                    step=step_columns,
                                    description='columns',
                                    readout=False,
                                    disabled=False,
                                    continuous_update=True,
                                    orientation='horizontal',
                                    slider_color='purple'))
    def _freeze_header(last_row, last_column):
        display(df.iloc[max(0, last_row-num_rows):last_row,
                        max(0, last_column-num_columns):last_column])

It's imports and a bunch of plotting/display helper functions.

Is there a way for me to bundle all of this up into a single pip package so that i can only have a line or two?

I'm imagining running:

pip install Genesis

then inside my jupyter notebook have:

import Genesis

and nothing else.


What I've tried:

I've tried making a genesis package that is basically a copy of this guide but with a single file called jupyter.py that contains the setup code above.

Then I run the following:

from Genesis import jupyter
jupyter.setup()

But it doesn't import pandas,numpy and matplotlib.pyplot for me. It makes sense because those packages are imported within the scope of the package. But any way to avoid that? Is it even possible in Python?


Solution

  • You can make a package with all your imports no problem, you just need to be careful of namespaces.

    Say I have a file:

    # genesis/__init__.py
    import pandas as pd
    import numpy as np
    ...
    

    Importing that genesis package will run that code, but it won't be accessible directly

    >>> import genesis
    >>> help(np)
    raceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'np' is not defined
    
    >>> help(genesis.np) # This should succeed
    ...
    

    You could address this with from genesis import * which would bring everything into the namespace you expect

    e.g.

    >>> from genesis import *
    >>> help(np) # This should succeed
    ...