Jupyter Notebook: save all images to svg by program - python

When I click the Download as markdown in the menu,
it will give me zip file with .md, .png, '.svg'
Note: I use set_matplotlib_formats('png', 'svg'), so the download file returns 2 image file formats.
Now, I want to save all the images in this notebook into svg by program (i.e., writing Python script), how can I do it? Maybe something like
save_images_to_svg('this_notebook.ipynb')
# and it will save all images to '.\images\*.svg'
What I know so far:
The link for Download as markdown is at here
this.element.find('#download_markdown').click(function () {
that._nbconvert('markdown', true);
});
It further binds to the _nbconvert at here
MenuBar.prototype._nbconvert = function (format, download) {
download = download || false;
var notebook_path = utils.encode_uri_components(this.notebook.notebook_path);
var url = utils.url_path_join(
this.base_url,
'nbconvert',
format,
notebook_path
) + "?download=" + download.toString();
this._new_window(url);
};
This means that the notebook sends a request to the backend to do the conversion.
I don't know where it is, but it seems like here, because it has a respond_zip method.
I think a quick hack is simply to download the file using python with the url from MenuBar.prototype._nbconvert.

Create the plot using matplotlib and save the image with the following command. It works in Sage 8.1 (windows). You will find the figures where your .ipynb file is located.
import numpy
import matplotlib.pyplot as plt
x = numpy.arange(-2 * numpy.pi, 2 * numpy.pi, 0.1)
func = numpy.sin(x)
plt.figure(figsize=(3.3, 3.3)) # inches
plt.plot(x, func, linewidth=2.0, color='blue')
plt.savefig('demo1.svg')
plt.savefig('demo1.pdf')
plt.savefig('demo1.eps')
plt.savefig('demo1.tif')
plt.show()
# plt.close()

Related

How to convert html map into image (png or jpg )

I am trying to save a map containing markers and also heatmap into an image.
Here is the code to display the map.
from ipywidgets import Layout
import geopandas
defaultLayout=Layout(width='3000px', height='3000px') # A very large image.
lat_lgn = [39.74248, 254.993622]
m_f = Map(center=lat_lgn, zoom=12, layout=defaultLayout)
marker_m = Marker(location=lat_lgn, draggable=False)
m_f.add_layer(marker_m)
m_f
Add some markers on it
arr_test1 = [39.74258, 254.993682]
arr_test2 = [39.76288, 254.988932]
arr_test3 = [39.79998, 254.991982]
all_loc = [arr_test1, arr_test2, arr_test3]
for cur_loc in all_loc:
point = CircleMarker(
radius=10,
location=cur_loc,
color='red',
fill_color="black",
)
m_f.add_layer(point)
time.sleep(0.001)
Save the map as html file. Works fine.
m_f.save('f_map.html', title='My Map')
The problem occurs, when I try to get an image, or pdf from the html.
import imgkit
import pdfkit
config = pdfkit.configuration(wkhtmltopdf='/usr/local/bin/wkhtmltopdf')
pdfkit.from_file('f_map.html', 'outpdf.pdf', configuration=config)
pdfkit.from_file('f_map.html', 'outjpg.jpg', configuration=config)
pdfkit.from_file('f_map.html', 'outpng.png', configuration=config)
The pdf file is blank
And macBook is not able the open neither the jpeg nor the png file.
To ckeck my dependencies, I have tried this:
import pdfkit
pdfkit.from_url('http://stackoverflow.com', 'out.pdf', configuration=config)
which works fine. However, once I change out.pdf to out.png, I cannot open the obtained file.
Does anyone has an idea, how I can solve the issue ?
I am trying to get hurge image. But it also did not work with a 300px X 300px image.
Any hints will be welcome.
One option (which admittedly is a little crude) is to use the selenium library to automatically open the HTML and from there take a screenshot which then is saved as an image.
The code will look like (I have given the code here according to MS Edge, but the code should be similar for other browsers):
from selenium import webdriver
from time import sleep
filename = '<Name (without path) of your HTML file here>'
MyBrowser = webdriver.Edge(r"<path to webdriver here>\\msedge.exe")
murl = r'file:\\{path}\{mapfile}'.format(path='<path to HTML here>',mapfile=mfilename)
MyBrowser.get(murl)
sleep(10) #this is not strictly necessary but is here in case you need time for map tiles to load
MyBrowser.save_screenshot('<Image_file_name>')
MyBrowser.quit()
Note that this will require you to install a webdriver for your browser in advance.

Bokeh Custom Extension Issues

I am attempting to learn about implementing bokeh custom extensions to create some widgets that I would like for my data project. I was attempting to follow along with this example here but I am having trouble running the example extensions that bokeh has provided. I am currently getting back an error of
ValueError: expected a subclass of HasProps, got class 'bokeh.models.sources.ColumnDataSource'
which is being caused when the DrawTool class calls source = Instance(ColumnDataSource) on line 80. I am not sure exactly what I am doing wrong right now but my first thought is it has something to do with the IDE I'm using? I'm currently using spyder(python 3.6) and have the most recent bokeh update 2.1.0.
This is my first experience with bokeh extensions so I am fairly clueless and I've been scouring the web for help but can't really find much. My current code is exactly what they have on the examples site but I will post it here for convenience,
from bokeh.core.properties import Instance
from bokeh.io import output_file, show
from bokeh.models import ColumnDataSource, Tool
from bokeh.plotting import figure
from bokeh.util.compiler import TypeScript
output_file('tool.html')
TS_CODE = """
import {GestureTool, GestureToolView} from "models/tools/gestures/gesture_tool"
import {ColumnDataSource} from "models/sources/column_data_source"
import {PanEvent} from "core/ui_events"
import * as p from "core/properties"
export class DrawToolView extends GestureToolView {
model: DrawTool
//this is executed when the pan/drag event starts
_pan_start(_ev: PanEvent): void {
this.model.source.data = {x: [], y: []}
}
//this is executed on subsequent mouse/touch moves
_pan(ev: PanEvent): void {
const {frame} = this.plot_view
const {sx, sy} = ev
if (!frame.bbox.contains(sx, sy))
return
const x = frame.xscales.default.invert(sx)
const y = frame.yscales.default.invert(sy)
const {source} = this.model
source.get_array("x").push(x)
source.get_array("y").push(y)
source.change.emit()
}
// this is executed then the pan/drag ends
_pan_end(_ev: PanEvent): void {}
}
export namespace DrawTool {
export type Attrs = p.AttrsOf<Props>
export type Props = GestureTool.Props & {
source: p.Property<ColumnDataSource>
}
}
export interface DrawTool extends DrawTool.Attrs {}
export class DrawTool extends GestureTool {
properties: DrawTool.Props
__view_type__: DrawToolView
constructor(attrs?: Partial<DrawTool.Attrs>) {
super(attrs)
}
tool_name = "Drag Span"
icon = "bk-tool-icon-lasso-select"
event_type = "pan" as "pan"
default_order = 12
static init_DrawTool(): void {
this.prototype.default_view = DrawToolView
this.define<DrawTool.Props>({
source: [ p.Instance ],
})
}
}
"""
class DrawTool(Tool):
__implementation__ = TypeScript(TS_CODE)
source = Instance(ColumnDataSource)
source = ColumnDataSource(data=dict(x=[], y=[]))
plot = figure(x_range=(0, 10), y_range=(0, 10), tools=[DrawTool(source=source)])
plot.title.text = "Drag to draw on the plot"
plot.line('x', 'y', source=source)
show(plot)
Your code works just fine for me with Bokeh 2.1.0. And is should not have anything to do with the IDE because it should not affect the runtime properties of your code. To be sure, you can run the script with Python manually.
If that still gives you the error, then maybe your Bokeh installation is corrupted. After all bokeh.models.sources.ColumnDataSource is a subclass of HasProps. Try creating the virtual environment from scratch.
Here's what I see when I run your code and interact with the plot a bit:
Just in case anyone runs into this issue in the future I thought I would post what I did here for anyone who is new to creating custom extensions and is having trouble finding a solution.
It turned out that my bokeh installation had corrupted as pointed out by Eugene. I went ahead and did a full rebuild of bokeh following Bokehs documents at Getting Started. After forking the latest bokeh repository I then ran into an issue with the anaconda environment trying to run this step where I found some Openssl corrupt files that were preventing me from creating an environment.
I found this fix on GitHub which worked for me with a thread of other possible solutions. After following the rest of the steps I successfully got the custom extensions running locally.
TLDR: The issue was a corrupt bokeh installation. If you are new to this and plan on doing custom extensions or using bokeh models, fork and clone a local build of bokeh rather than relying on the quick installation method.

How can i view an html output file from a gmplot draw command inside of a Google Colab notebook?

I am trying to use colab and googlemaps to display a heatmap image overlayed onto google maps. I did some research and found 2 possible solutions at this link but both solutions are not working.
Display / Render an HTML file inside Jupyter Notebook on Google Colab platform
Maybe something has changed recently?
Here is my code:
pip install gmplot
import gmplot
gmap1 = gmplot.GoogleMapPlotter(30.3164945,
78.03219179999999, 13, apikey='AIzaSyBCyhpxDYIxIq9uINYxDK5aIjWSokUvsvY' )
gmap1.draw( "map11.html" )
import os
print(os.getcwd())
!ls
/content
map11.html sample_data
import IPython
IPython.display.HTML(filename='/content/map11.html')
nothing is displayed.
from IPython.display import IFrame
IFrame(src='/content/map11.html', width=900, height=600)
localhost refused to connect.
Your local browser cannot read a file from the remote VM filesystem. Instead of passing the HTML by filename, try displaying the HTML content directly:
IPython.display.HTML(open('/content/map11.html').read())

How can I generate a wordcloud using matplotlib, store it inside a variable send it and render it on a HTML page?

My python code
What i'm doing here is receiving a JSON by POST method, extracting a certain property from it to form a string. Afterwards I do generate a wordcloud using matplotlib library.
My goal is to somehow "generate" an image WITHOUT STORING IT ON MY SERVER, as I would think it's a variable or something alike that. And then "send" it to a HTML page and show it.
import json
#app.route('/wordcloud', methods=['POST', 'GET'])
def wordcloud():
print('****************************************')
jsoncito = request.form['wordcloud']
print('22222222222222222222222222222222222222222')
jsonParaPasar = json.dumps(jsoncito)
text = ""
newjson = json.loads(request.form['wordcloud'])
neww = ast.literal_eval(newjson)
for x in neww:
text = text + x['respuesta'] + " "
wordcloud = WordCloud(width=480, height=480, margin=0).generate(text)
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.margins(x=10, y=10)
I read maybe I can turn it into a numpy array in order to send it, but I don't know how to turn that into a proper image!

Python configure pdfkit on windows

I started to learn python recently and I want to convert existing html file to pdf file. It is very strange, but pdfkit seems to be the only lib for pdf docs for python.
import pdfkit
pdfkit.from_file("C:\\Users\\user\Desktop\\table.html", "out.pdf")
An error occurs:
OSError: No wkhtmltopdf executable found: "b''"
How to configure this lib properly on windows to make it work? I can't get it :(
It looks like you need to install wkhtmltopdf. For windows, the installer can be found at https://wkhtmltopdf.org/downloads.html
Also check out a post by this guy, who is having the same problem: Can't create pdf using python PDFKIT Error : " No wkhtmltopdf executable found:"
I found working solution.
If you want to convert files to pdf format just don't use python for this purpose.
You need to include DOMPDF library into your php script on your local/remove server. Something like this:
<?php
// include autoloader
require_once 'vendor/autoload.php';
// reference the Dompdf namespace
use Dompdf\Dompdf;
if (isset($_POST['html']) && !empty($_POST['html'])) {
// instantiate and use the dompdf class
$dompdf = new Dompdf();
$dompdf->loadHtml($_POST['html']);
// (Optional) Setup the paper size and orientation
$dompdf->setPaper('A4', 'landscape');
// Render the HTML as PDF
$dompdf->render();
// Output the generated PDF to Browser
$dompdf->stream();
} else {
exit();
}
Then in your python script you can post your html or whatever content to your server and get generated pdf file as a response. Something like this:
import requests
url = 'http://example.com/html2pdf.php'
html = '<h1>hello</h1>'
r = requests.post(url, data={'html': html}, stream=True)
f = open('converted.pdf', 'wb')
f.write(r.content)
f.close()

Categories