Jinja rendering matplotlib plots? - python

I am looking at combining matplotlib and jinja2 to produce html pages.
What I do now is just including an image previously produced by matplotlib as a reference in my html page. The result is really static.
I've seen related questions like here or here, but none related to matplotlib/jinja integration (ultimately I'd like interactivity but It does not seem to be simple enough for me).
Is there any alternative to what I do ?

Ipython notebook from v1.x uses jinja2.
You can create inline images in the notebook and then convert it to a static html with nbconvert. You can provide custom css and you can customise the output html to hide code cells, cell numbers, ...

Related

Save interactive matplotlib figures to html

I realize that there have been quite a few questions asked on this over the years, but the answers I have found thus far have been fairly unsatisfactory, and that may be just because there is no way to easily accomplish this. I have a notebook that generates interactive figures with the % matplotlib notebook magic command, but when I use nbconvert to get the HTML for the notebook, the interactivity of the figures is lost. Is there a way to save the javascript and raw data of each figure directly into the HTML output to maintain interactivity? If not, can someone outline a few possible alternative solutions that I can look into?

Rendering a pandas dataframe as HTML with same styling as Jupyter Notebook

I would like to render a pandas dataframe to HTML in the same way as the Jupyter Notebook does it, i.e. with all the bells and wistles like nice looking styling, column highlighting, and column sorting on click.
pandas.to_html outputs just a plain HTML table and requires manual styling etc.
Is the dataframe rendering code used by jupyter available as a standalone module that can be used in any web app?
Also, are the assets such as js/css files decoupled from jupyter so that they can be easily reused?
This works well for me
def getTableHTML(df):
"""
From https://stackoverflow.com/a/49687866/2007153
Get a Jupyter like html of pandas dataframe
"""
styles = [
#table properties
dict(selector=" ",
props=[("margin","0"),
("font-family",'"Helvetica", "Arial", sans-serif'),
("border-collapse", "collapse"),
("border","none"),
# ("border", "2px solid #ccf")
]),
#header color - optional
# dict(selector="thead",
# props=[("background-color","#cc8484")
# ]),
#background shading
dict(selector="tbody tr:nth-child(even)",
props=[("background-color", "#fff")]),
dict(selector="tbody tr:nth-child(odd)",
props=[("background-color", "#eee")]),
#cell spacing
dict(selector="td",
props=[("padding", ".5em")]),
#header cell properties
dict(selector="th",
props=[("font-size", "100%"),
("text-align", "center")]),
]
return (df.style.set_table_styles(styles)).render()
iris = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv')
getTableHTML(iris)
Some points to clarify first:
Pandas doesn't have anything to do with the styling, and the styling happens to all HTML tables, not only dataframes. That is easily checked by displaying an HTML table in Jupyter (example code at the end of the answer).
It seems that your Jupyter or one of your installed extensions is doing "extra" styling, the default style doesn't include column sorting or column highlighting. There is only odd/even rows coloring and row highlighting (checked on Jupyter source code and my local Jupyter installation). This means that my answer may not include all the styling you want.
The Answer
Is the dataframe rendering code used by jupyter available as a standalone module that can be used in any web app?
Not exactly a standalone module, but all the tables formatting and styling seem to be attached to the rendered_html class. Double-checked that by inspecting the notebook HTML in Firefox.
You can use the .less file linked above directly or copy the required styles to your HTML.
Also, are the assets such as js/css files decoupled from jupyter so that they can be easily reused?
Like any well-designed web project (and actually any software project), the packages and modules are well separated. This means that you can re-use a lot of the code in your project with minimal effort. You can find most of the .less styling files in Jupyter source code here.
An example to check if the styling happens to all HTML tables:
from IPython.display import HTML
HTML('''<table>
<thead><tr><th></th><th>a</th><th>b</th></tr></thead>
<tbody>
<tr><th>0</th><td>1</td><td>3</td></tr>
<tr><th>1</th><td>2</td><td>4</td></tr>
</tbody>
</table>''')

Exporting Jupyter Notebook as either PDF or HTML makes all HTML plaintext

I am just getting started with Jupyter Notebook and I'm running into an issue when exporting.
In my current notebook, I alternate between code cells with code and markdown cells. (Which explain my code).
In the markdown cells, sometimes I will use a little HTML to display a table or a list. I will also use the bold tag <b></b> to emphasize a particular portion of text.
My problem is, when I export this notebook to PDF (via the menu in Jupyter Notebook) all of my HTML gets saved as plaintext.
For example, instead of displaying a table, when exporting to PDF, the HTML will be displayed instead. <tr>Table<tr> <th>part1</th>, etc.
I've tried exporting to HTML instead, but even the HTML file displays the HTML as plaintext.
I tried downloading nbconvert (which is probably what I'm doing when I use the jupter GUI anyways) and using that via terminal, but I still get the same result.
Has anyone run into this problem before?
I tried to export it to html and it worked normally.
Where did you define your html? Did you used the Markdown textfields?
Alternatives:
I don't have the nbconverter, but what about exporting it to html and use another tool to convert it to a pdf?
Use markdown language, it provides tables. Link:
https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet
Consider upgrading your notebook
I fixed this myself.
It turns out that somewhere in the code, there was a tag.
Although it did not run the entire length of the cell, the fact that the plaintext tag was there at all changed the dynamic of the cell.
Next, I had strange formatting errors (Text was of different size and strangely emphasized) when using = as plaintext in the cell. When opening the cell for editing, these = symbols were big bold and blue. This probably has something to do with the markdown language.
This was solved by placing the = on the same line as other text.
I did have to convert the page to HTML, then use a firefox addon to convert to PDF.
Converting to PDF from jupyter notebook uses LaTeX to transcribe the page, and all html is converted to plaintext.
The page appeared as normal with html tables, and normal html in the markdown cell. I just had to be careful with any extraneous tags.
If anyone else encounters this problem, check your html tags, and make sure that you are not accidentally doing something in markdown language.

Exporting figures from Bokeh as svg or pdf?

Is it possible to output individual figures from Bokeh as pdf or svg images? I feel like I'm missing something obvious, but I've checked the online help pages and gone through the bokeh.objects api and haven't found anything...
There is no way to save PDF currently, but as of Bokeh 0.12.6, it is now possible to export PNG and SVG directly from
Python code.
Exporting PNGs looks like this
export_png(plot, filename="plot.png")
And exporting SVGs looks like this
plot.output_backend = "svg"
export_svgs(plot, filename="plot.svg")
There are some optional dependencies that need to be installed.
You can find more information in the Exporting Plots section of the User Guide.
In the meantime... as a workaround, until we get a native support, you can use phantom.js to convert the HTML output into a pdf file. We use it in our example testing directory to convert HTML generated plots into png images, but you could also get pdf images:
https://github.com/ContinuumIO/bokeh/blob/master/examples/test#L217
And more info here:
http://phantomjs.org/screen-capture.html
It seems that since bokeh uses html5 canvas as a backend, it will be writing things to static html pages. You could always export the html to pdf later.
So, it's 2022 now and there's no direct support for exporting images as pdf.
However, there is a alternative way which works just as well.
First, as the other answers have mentioned, set the backend to 'svg'.
plot.output_backend = "svg"
then save the image as an svg file. Do not save it as an html file as this will likely lead to extra space around the actual image.
Then use any online svg to pdf convertor to get the pdf equivalent of the svg.

Is there a workaround to get floating divs in Report Lab?

I generate PDFs with the xhtml2pdf Python package. The output is not optimal. I use floating divs in order to place images and text on the page. In HTML this works but after PDF rendering, images and text ar placed underneath eachother which is not what I want. From surfing the web I learned that the Report Lab package that is used by xhtml2pdf can not handle floating divs. Does a workaround exist? I have tried webkit rendering via QT but the resulting PDFs are of low quality, i.e. character spacing is completely wrong.
If you cannot achieve the results you need with xhtml2pdf, I suggest you use ReportLab directly. ReportLab contains support for RML, ReportLabs own markup language that lets you easily create formatted text, and has a support library called Platypus that makes layout fairly simple using Python objects to represent document parts and page layouts.
The reason you are having problems, by the way, is that xhtml2pdf has to essentially act like a HTML rendering engine that outputs to PDF rather than the screen directly. As it took a long time and a lot of effort to make good rendering engines for browsers, so, too, does it seem that xhtml2pdf will take a lot of effort to make it of similar quality. This isn't to say that xhtml2pdf is bad, just that it's going to take time for it to be as good as rendering in a browser, and if PDF output for its own sake is what you really are interested in, I think using ReportLab directly is a better choice.

Categories