Save plotly figure interactively (html) whilst preserving LaTeX font - python

I created a plotly figure using python and I am aware that one can save the interactive figure in html format by using:
fig.write_html("name_of_figure.html")
For the axis labels, as well as the title of the figure, I used LaTeX fonts like this:
fig.update_layout(title=r'$\text{Some title}_2$')
When I render it in my browser directly the LaTeX fonts are displayed correctly. However, when I save the figure in .html format, the title, as well as the axis labels, are not rendered using LaTeX fonts. I rather see the plain text like $\text{Some title}_2$.
What can I do to circumvent that problem?

Add an include_mathjax = 'cdn' parameter to .write_html.
And read the documentation of write_html function carefully :)
include_mathjax: bool or string (default False)
Specifies how the MathJax.js library is included in the output html div string. MathJax is required in order to display labels with LaTeX typesetting.
If False, no script tag referencing MathJax.js will be included in the output.
If 'cdn', a script tag that references a MathJax CDN location will be included in the output. HTML div strings generated with this option will be able to display
LaTeX typesetting as long as internet access is available.
If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point the
resulting HTML div string to an alternative CDN.
import plotly.express as px
fig = px.line(x = [0,1,2], y = [0,1,4])
fig.update_layout(title=r'$\text{Some title}_2$')
fig.write_html("example_figure.html", include_mathjax = 'cdn')

Related

How to save a Bokeh plot as PDF?

I'm working with Bokeh a lot and I'm looking for a way to create a PDF from the figure I created.
Is there an option to achieve this goal?
This is possible with a combination of the three python package bokeh, svglib and reportlab which works perfect for me.
This will include 3 steps:
creating a bokeh svg output
read in this svg
saving this svg as pdf
Minimal Example
To show how this could work please see the following example.
from bokeh.plotting import figure
from bokeh.io import export_svgs
import svglib.svglib as svglib
from reportlab.graphics import renderPDF
test_name = 'bokeh_to_pdf_test'
# Example plot p
p = figure(plot_width=400, plot_height=400, tools="")
p.circle(list(range(1,6)),[2, 5, 8, 2, 7], size=10)
# See comment 1
p.xaxis.axis_label_standoff = 12
p.xaxis.major_label_standoff = 12
# step 1: bokeh save as svg
p.output_backend = "svg"
export_svgs(p, filename = test_name + '.svg')
# see comment 2
svglib.register_font('helvetica', '/home/fonts/Helvetica.ttf')
# step 2: read in svg
svg = svglib.svg2rlg(test_name+".svg")
# step 3: save as pdf
renderPDF.drawToFile(svg, test_name+".pdf")
Comment 1
There is an extra information used for axis_label_standoff and major_label_standoff because the ticks of the x-axis are moving without this definition a bit up and this looks not so good.
Comment 2
If you get a long list of warnings like
Unable to find a suitable font for 'font-family:helvetica'
Unable to find a suitable font for 'font-family:helvetica'
....
Unable to find a suitable font for 'font-family:helvetica'
the ppdf is still created. This warning appears because the default font in bokeh is named helvetica, which is not known by svglib. svglib looks for this font at a defined place. If this font is not there, the message appears. This means bokeh will use its own default font instead.
To get rid of this message you can register a font in svglib like this
# name in svglib, path to font
svglib.register_font('helvetica' , f'/{PATH_TO_FONT}/Helvetica.ttf')
right before calling svglib.svg2rlg().
Output
This code will create the same figure twice, once with the suffix .svg and once with the suffix .pdf.
The figure looks like this:

Problem regarding highlighting text in pdf document python

I am trying to write a python script that would automate the process of finding text in a pdf and highlight according
I am using pymupdf module of python. It works for some pdf. However, when for the target pdf(drawing of components and property tables) it would save output as a blank pdf with no data and some blank highlights.
import fitz
doc=fitz.open("c5.pdf")
page = doc[0]
text = "a"
text_instances = page.searchFor(text)
for inst in text_instances:
highlight = page.addHighlightAnnot(inst)
doc.save("out.pdf", garbage=4, deflate=True, clean=True)
Your PDF probably contains elements which appear like text but are something else. It may be that they are just some type of graphics or image.
In that case the text search of course cannot find anything.
Please submit an issue on my repo for PyMuPDF with some sample PDF to allow me investigating this.

Turning HTML generated from gmplot into the actual map

Afternoon,
I am trying to use the gmplot library to plot a load of lats/long coordinates I have. If I just take the example on the pypi page, see below (https://pypi.python.org/pypi/gmplot/1.0.5) and run it, I generate the HTML file but I don't know how to turn this into the actual map. Any ideas?
gmap = gmplot.GoogleMapPlotter(37.428, -122.145, 16)
gmap.plot(latitudes, longitudes, 'cornflowerblue', edge_width=10)
gmap.scatter(more_lats, more_lngs, '#3B0B39', size=40, marker=False)
gmap.scatter(marker_lats, marker_lngs, 'k', marker=True)
gmap.heatmap(heat_lats, heat_lngs)
gmap.draw("mymap.html")
gmap.draw("mymap.html")
This will generate the map in your folder where your notebook is, or your file where you have written the code. If you want the map to be generated at some other location specify the path at gmap.draw(<path for map>).
This map can be opened in any browser. Generated map by gmplot has javascript based zoomin capability and the entire map can be accessed through the browser

How to prevent plotly from plotting automatically

I just discovered plotly and like it so far. I have this code provided by the main website
import plotly.plotly as py
from plotly.graph_objs import *
trace0 = Scatter(
x=[1,2,3,4],
y=[10,15,13,17]
)
trace1 = Scatter(
x=[1,2,3,4],
y=[16,5,11,9]
)
data = Data([trace0, trace1])
unique_url = py.plot(data, filename='basic-line')
I am curious about two things:
1) When I run this code, my browser automatically pops up and shows me the graph. All I want is the url so that I can later embed it in an html file. Is there a way to turn off the feature that opens my browser and shows me the graph?
2) Is there a way to get rid of the 'Play with this data' link?
I have combed through the documentation provided, but have come up empty-handed on these two issues.
To disable pop-ups you could use auto_open=FALSE and try the following
py.plot(data, filename='basic_line', auto_open=False)
py.plot(data, show_link=False) will take that link off (if you are referring to the link that says Export to plot.ly). At least it does using:
import plotly.offline as py. As for the link at the top (when you hover your mouse over the graph), I'm trying to get rid of the Save and edit plot in cloud but only find options for that under the java script version... and that hides the whole bar which has other useful items on it (javascript option is: {displayModeBar: false}). Obviously I am finding the reference to "play with this data" ambiguous. You can see the workaround I wrote here: Adding config modes to Plotly.Py offline - modebar
You can easily remove that Export to plot.ly link in the offline graph.
Open your saved html file in a text editor. and search for. {"showLink": true, "linkText": "Export to plot.ly"}
And change the true value to false.

Python: How to make Reportlab move to next page in PDF output

I'm using the open source version Reportlab with Python on Windows. My code loops through multiple PNG files & combines them to form a single PDF. Each PNG is stretched to the full LETTER spec (8.5x11).
Problem is, all the images saved to output.pdf are sandwiched on top of each other and only the last image added is visible. Is there something that I need to add between each drawImage() to offset to a new page? Here's a simple linear view of what I'm doing -
WIDTH,HEIGHT = LETTER
canv = canvas.Canvas('output.pdf',pagesize=LETTER)
canv.setPageCompression(0)
page = Image.open('one.png')
canv.drawImage(ImageReader(page),0,0,WIDTH,HEIGHT)
page = Image.open('two.png')
canv.drawImage(ImageReader(page),0,0,WIDTH,HEIGHT)
page = Image.open('three.png')
canv.drawImage(ImageReader(page),0,0,WIDTH,HEIGHT)
canv.save()
[Follow up of the post's comment]
Use canv.showPage() after you use canv.drawImage(...) each time.
( http://www.reportlab.com/apis/reportlab/dev/pdfgen.html#reportlab.pdfgen.canvas.Canvas.showPage )
Follow the source document(for that matter any tool you are using, you should dig into it's respective website documentation):
http://www.reportlab.com/apis/reportlab/dev/pdfgen.html

Categories