Customize font for Pandas dataframe in Juypter lab console using CSS - css

I am trying to add CSS rules to my Jupyter Lab Console to customize the look of only pandas dataframes and I have successfully done this interactively in the console. What I want is to have my CSS rules applied to the Jupyter Lab Console when it starts so that I don't have to do this interactively. I have successfully added these style customizations to the pandas dataframe itself (df.style.apply()) but I don't want to have to add it to every dataframe I create interactively.
Pandas dataframes are classed as .dataframe. I have created a Jupyter Lab start-up file called "00-first.py" and have it in the .ipython/profile_default/startup/ directory. The file contents are:
from IPython.display import HTML, display
import pandas as pd
import numpy as np
style = '''<style>
.dataframe td {font-family:"Liberation Mono";}
.dataframe th, .dataframe tr, .dataframe td {padding-top:0.1em; padding-bottom:0.1em;}
</style>'''
display(HTML(style))
display(HTML("Environment personalization complete."))
When I launch the console I can confirm the 00-first.py file has been executed as dir() shows the "style" variable, pd and np. The message string does not print out and the style does not appear in the CSS of the web page.
If I create a dataframe, it is displayed with the default css font. To get the styling to take place, I manually run display(HTML(style)) and then all dataframes now have the new css style.
I am trying remove having to type display(HTML(style)) at the beginning of each console session and want the startup script "00-frist.py" to handle this.
I am using Jupyter Lab 1.1.4 on Linux Manjaro Linux 5.6.7-1-MANJARO x86_64 GNU/Linux using Firefox 75.0.
How do I do this or is there a better way to do this?
Before: without styling
After: with styling

I tried multiple incantations of NotebookApp.extra_static_pathsList as suggested by #jayveesea but could not get this method to work. The solution I found turned out to be quite simple and that is to edit the base CSS file, adding my CSS selectors there.
Find your Jypyter application directory using jupyter lab path from the command prompt. This will be something like /home/fred/anaconda3.
Find the index.css file for the theme you use. This file will be located under your Jupyter Application directory, under the directory of the theme you are using. For example, if your Jupyter application directory is '/home/fred/anaconda3' and the theme you are using is 'theme-light-extension', then the index file will be located at /home/fred/anaconda3/share/jupyter/lab/themes/#jupyterlab/theme-light-extension/index.css
Add your CSS selectors to the file.
/* pandas dataframe customizations */
.dataframe td {font-family:"Liberation Mono";}
.dataframe th, .dataframe tr, .dataframe td {padding-top:0.1em; padding-bottom:0.1em;}
Restart your Jupyter console and you should see all pandas dataframes formatted following these rules.
One downside to this method is that you have to add your CSS rules to any extensions you want to support these rules, but this works for me since I don't switch extensions.

Take a look here for using the config file for jupyter. In particular NotebookApp.extra_static_paths option:
NotebookApp.extra_static_pathsList Default: []
Extra paths to search for serving static files.
This allows adding javascript/css to be available from the notebook
server machine, or overriding individual files in the IPython
UPDATE:
It seems like the above method might be broken and maybe abandoned. Another solution is to use the following path to store custom CSS: .jupyter\custom which does not need any update to the config file.
So in this case .jupyter\custom\custom.css would contain:
.dataframe td {font-family:"Liberation Mono";}
.dataframe th, .dataframe tr, .dataframe td {padding-top:0.1em; padding-bottom:0.1em;}

Related

Change jupyter notebook style in VS Code (css file)

I encountered some problems when trying to change the layout of the markdown cells of my jupyter notebook.
I do not like the default display of tables and I want to change it. I am trying to use the default css from github.
I do not have lines that separates the rows and columns:
I tried to set this in my settings.json but it did not work
"markdown.styles": [
"./.vscode/github-markdown.css"
]
I have also tried to add something find here (https://www.kaggle.com/learn-forum/129348)
from IPython.display import HTML
HTML(''.format(open('.vscode/github-markdown.css').read()))
Can you help me ?

Is there any way to open local file directly from 'Elements > Styles' tab in Chrome devtools?

I'm using the Chrome devtools persistence feature with browser-sync and sass.
I set a Workspace pointing to my scss folder and I can edit scss files from Chrome and have all css files created correctly, applied to browser real-time and saved in hard drive.
However when I select an element on the Elements > Styles tab and make some changes, the changed file is the http://localhost:3000... one so changes are not kept. Then I still have to find the local file in the Sources tab to copy these changes.
I'm not sure if this is the best we can get but if we could either open the local file directly from the Elements > Style tab instead of the http://localhost:3000... file or somehow automatically copy any changes in the http://localhost:3000... file to local file the workflow would be even easier and faster.
Does any one knows how to accomplish that, even using some app/extension?
UPDATE:
From Rohit answer I found that if I turn off css source maps in devtools settings then it is correctly synced, showing the green circle on the Elements > Style and keep my changes, although it still pointing to http://localhost:3000...style.css file.
However then it only changes this file, not the specific partials/*.scss file and if I run sass compiler it overrides the css with the old code.
With the css source maps on Chrome finds my partial scss correctly but doesn't show the green circle so it's not synced and doesn't keep changes.
The problem seems to be with syncing scss files instead of css.
I was trying with a Workspace pointing to my root scss folder, also tried pointing it to the direct parent of the file beeing edited and still not syncing corretly.
This is a shot in the dark but,I beleive if you add the parent folder of the files you are working on from Devtools > Sources Tab > Filesystem tab > Add folder to workspace.
Like so :
Then navigate to your folder, and add reload the page. After reloading if you see green
like so:
It means it is synced and will update without you going to the sources tab.
Adding the root of my project to the Workspace synced scss files correctly. Now when I click an element on the Element > Styles tab, Quick source opens the right file at the right scss rule but doesn't follow my changes in the Element > Styles tab (as it does using pure css) and I still need to copy changes to Quick source or edit there directly, save and wait sass compilation to apply changes on screen.
The workflow is much easier now but I'm not choosing this as the correct anwser because is not "as live as css" yet and maybe someone knows how to do this final step.
PS: browser-sync is not needed in this setup, just something to compile sass and Chrome apply changes automatically.

Access the content of css files with Webpacker

Using Webpacker I can load css files and they get output in the stylesheet pack files, but sometimes I'd like to access the CSS in these files from within javascript for use say in a WYSIWYG editor's config (specifying some extra styles for the IFRAME). The other option is to be able to access the public path of a css file loaded in like so:
import froala_style from '../../../css/froala.css'
My suspicion is that it's to do with the css loader that comes with Webpacker. Its job is to load the css and compile it out to a seperate file. I think that one can't have two css loaders at the same time? Could the answer be to apply filters to a custom loader so that it takes effect on only the file I'm wanting to load in as text or the path?
One can override the existing loaders for a particular import like so:
import froala_style from '!css-loader!../../../css/froala.css'
Prepending the ! overrides existing loaders allowing us to specify our own. In this example one can call froala_style.toString() to receive the contents of the CSS file.
For reference: https://webpack.js.org/concepts/loaders/#inline

Shared configuration for jupyter notebook for multiple servers

I am working in an environment with multiple servers and would like to share my .jupyter configuration amongst the servers such that I don't have to keep them in sync manually. This can be achieved easily by setting the JUPYTER_CONFIG_DIR environment variable to a shared location.
However, I would like to use different CSS style sheets for each server such that it is obvious which one I am working on. For example, on the first server, I would like to have a red background:
#notebook { background: red; }
and on the second, I would like to have a blue background.
#notebook { background: blue; }
I thought I might be able to achieve this by appending different paths to the extra_static_paths depending on the hostname of the jupyter server. However, the HTML of the notebook looks for custom/custom.css and the files indicated by extra_static_paths are served from static/... such that I cannot replace the custom css file in this manner.
Is there a better approach?
I think that can be achieved with profiles, but the documentation is scarce on the topic.
EDIT: I was wrong. According to this question the profiles are gone since jupyter 4.x, so unless you want to go into managing shared directories and files through bash scripting, it seems the following is the only solution.
While technically a workaround, this might be preferable: use the Stylish browser extension. I use it to quickly1 swap between the notebook's default white theme and a darker one.
How Stylish works
Basically it injects custom CSS in the pages that are matched by a rule at the top of a theme. You can write your own CSS theme or download one from their website. For a jupyter example, I am using this one. It matches on the following rules:
url-prefix("http://localhost:8888/"),
url-prefix("http://127.0.0.1:8888/"),
url-prefix("http://localhost:8889/"),
url-prefix("http://localhost:8890/")
What you can do is duplicate this theme and have each one of them match on a single port, which corresponds to the server where you want it applied. Then you can start your servers with the --port=xxxx option.
1 -- You can change the notebook's theme by placing a custom CSS file somewhere in the jupyter's config directory, but if you want to change it on the fly you have to replace that file every time. With stylish, the change is 1 click away.

New ipython notebook templating

Is it possible to define some template content cells which all new ipython notebooks include when being created?
I'd like my notebooks to include some standard CSS using this method and possibly also have a markdown cell with links I'm frequently using .
Thanks to #Jakob for the help.
To get permanent customised CSS within the notebooks, I needed to create <myprofile>/static/custom/custom.css in my .ipython user folder folder.
This worked quite ok. I used the firefox's webdev tools to find the css items and classes in the ipython notebook and managed to get a monokai-ish style:
I also learned from here that you can inject javascript which might make it possible to add default content to new notebooks. I haven't tried this one yet though.
Edit: if interested, the css file lives here. The monokai colors are based on .cm-s-ipython, which I think is similar what sublime text is using.

Resources