I am trying to show a graph using seaborn and mpld3 but in a .html file. When I use the command mpld3.show(), a new window pops and the graph is shown in a local webserver created (like the documentation describes). However, when trying to save it in a .html file, the graph comes empty but I can see some icons like move and zoom avaliable....
With mpld3.show()
sns.set(style="whitegrid")
sns.barplot(x=df.index.tolist(), y=df['Salário'])
mpld3.show()
Graph how its supposed to be:
Trying to save to .html file using save_html():
sns.set(style="whitegrid")
sns.barplot(x=df.index.tolist(), y=df['Salário'])
fig = plt.figure()
mpld3.save_html(fig, "./templates/graph_exp.html")
Bugged graph with working icons
Can someone help me make this graph appear normal saving to a .html file? :)
I am not sure how save_html() works but this is what i use on my flask website.
This solution works if you do not need to save the image.
import base64
import io
pngImage = io.BytesIO()
FigureCanvas(fig).print_png(pngImage) #fig is my matPlotlib instance of Figure()
# Encode PNG image to base64 string
image = "data:image/png;base64,"
image += base64.b64encode(pngImage.getvalue()).decode('utf8')
then in html use:
<img src="{{image}}">
Related
I have a loop where I want to render some sankeys to .png files.
Checking some docs here:
https://nbviewer.jupyter.org/github/ricklupton/ipysankeywidget/blob/master/examples/Exporting%20Images.ipynb
I would expect sankey.save_svg('test.svg') to work.
From reading those docs, there's a caveat that trying to display and then save won't work, but I'm not trying to display, I just want to save a list of images. However I'm getting the same warnings.warn('No png image available! Try auto_save_png() instead?') error and cannot save.
If I run one line at a time, and return the sankey and let it display in the normal run of a python notebook, things work ok... So it seems there's something that happens when you let the notebook display a sankey that isn't happening when I'm just trying in a loop to render them to files.
from ipywidgets import Layout
from ipysankeywidget import SankeyWidget
def draw_one(use_case, limit=50):
df = Cli.query_paths(use_case=use_case, limit=limit)
layout = Layout(width="2000", height="500")
fpath = f'./data/ignored/images/{use_case}-{limit}.png'
# with or without: .auto_save_png(fpath)
sankey = SankeyWidget(links=df.to_dict('records'), layout=layout)
sankey.save_png(fpath)
cases = [
'INTL',
'PAC',
]
def loop():
for use_case in cases:
print('sk:', use_case)
sk = draw_one(use_case, limit=50)
loop()
I have tried to export a visualisation of data with ipyleaflet as PNG or any other file format but i could not find a method that is working. For example in folium there is map.save(path). Is there a library or method in ipyleaflet that i have missed in my research which helps me to accomplish my goal?
here is some example code to generate a map
from ipyleaflet import *
center = [34.6252978589571, -77.34580993652344]
zoom = 10
m = Map(default_tiles=TileLayer(opacity=1.0), center=center, zoom=zoom)
m
I'd like to export this map as an image file without taking a screenshot manually.
I found two sources that allow to export javascript leaflet maps:
https://github.com/aratcliffe/Leaflet.print and https://github.com/mapbox/leaflet-image
Unfortunately i was not able to make use of them in python.
My colleague and I found a decent work around for ipyleaflet (python) image export. Here is how it works. The folium library is required for an export. The GeoJson data in this example is already prepared with style properties:
import folium
map = folium.Map([51., 12.], zoom_start=6,control_scale=True)
folium.GeoJson(data).add_to(map)
map.save('map.html')
This is how the result looks:
The html file can be further processed in python (windows) with subprocess calls to make a PDF or PNG out of it. I hope this helps as the ipyleaflet doc for python is almost non existant.
For generating html, you can use ipywidgets
from ipywidgets.embed import embed_minimal_html
embed_minimal_html('map.html', views=[m])
If you want to make a PNG, you can use ipywebrtc, more specifically:
https://ipywebrtc.readthedocs.io/en/latest/ImageRecorder.html
https://ipywebrtc.readthedocs.io/en/latest/WidgetStream.html
Or in code:
from ipywebrtc import WidgetStream, ImageRecorder
widget_stream = WidgetStream(widget=m, max_fps=1)
image_recorder = ImageRecorder(stream=widget_stream)
display(image_recorder)
Saving the PNG:
with open('map.png', 'wb') as f:
f.write(image_recorder.image.value)
Or converting to pillow image for preprocessing:
import PIL.Image
import io
im = PIL.Image.open(io.BytesIO(image_recorder.image.value))
ipyleaflet supports saving as html. Export of svg and png does not seem to be supported.
https://ipyleaflet.readthedocs.io/en/latest/map_and_basemaps/map.html#save-to-html
m.save('output.html')
I created an issue ticket for ipyleaflet:
https://github.com/jupyter-widgets/ipyleaflet/issues/1083
I'm trying to edit the modeBarButtons of a plotly graph such that the 'save and edit plot in cloud' function becomes disabled. At first this didn't seem possible in Python. But this post pointed out a workaround for Python, by casting the object to HTML and editing the HTML code.
Unfortunately, the 'save and edit plot in cloud' functionality remains when I try the example code below:
import numpy as np
from IPython.display import display, HTML
from plotly.offline import download_plotlyjs, init_notebook_mode, plot
import plotly
import plotly.graph_objs as go
plotly.offline.init_notebook_mode()
# create sin data to plot
x = np.arange(0.0, 100.0, 0.1)
y = np.sin(x)
# create plot data, edit and plot
trace0 = go.Scatter(x=x,y=y, name="Sin")
HTML_code = plot([trace0], show_link=False, auto_open=False, output_type='div')
HTML_code = HTML_code.replace('modeBarButtonsToRemove:[]',
'modeBarButtonsToRemove:["sendDataToCloud"]')
display(HTML(HTML_code))
[Edit] Write to file:
The button is successfully removed when the edited HTML is written to file and opened in a browser.
Reloading the edited file into my notebook was unsuccessful:
from IPython.display import display, HTML
with open('./temp-plot.html', 'r') as file :
tempHTML = file.read()
display(HTML(tempHTML))
Javascript error adding output!
ReferenceError: Plotly is not defined
See your browser Javascript console for more details.
Using output_type='div' instead of output_type='file' (my preferred approach due to write restrictions for the final product):
The notebook seems to 'reload' plotlys' standard configuration and only insert the data from the HTML, leaving the edited JavaScript unused.
Any suggestions?
Regards,
Koen
I am creating a plot using the following code, and saving it to a path. However, the plot opens a new window without me explicitly calling plt.show(). Does anyone know how to stop the window opening?
arr1 = np.random.rand(150,500)
arr2 = np.random.rand(150,500)
fig = plt.figure()
a=fig.add_subplot(1,2,1)
imgplot = plt.imshow(arr1)
a.set_title('Image 1')
a.xaxis.set_visible(False)
a.yaxis.set_visible(False)
a=fig.add_subplot(2,2,1)
imgplot = plt.imshow(arr2)
a.set_title('Image 2')
a.xaxis.set_visible(False)
a.yaxis.set_visible(False)
plt.savefig('C:/Users/.../fig.png', bbox_inches='tight')
If I understand your question, what you're trying to do is save the plot without displaying it, correct?
To do that, you need to get a Canvas where your figure is added and then output that canvas to a binary string, which you save to a file. Something like this should work:
from matplotlib.backends.backend_agg import FigureCanvasAgg
from io import BytesIO
canvas = FigureCanvasAgg(my_figure)
image_content = BytesIO()
canvas.print_png(image_content, dpi=my_dpi_resolution)
# Now image_content has your image data, which you can write to a file:
open("my/file.png", "wb").write(image_content)
# This outputs PNG images but other formats are available (print_jpg or print_tif, for instance).
Try %pylab inline -- then program won't make another window
I like to produce high quality plots and therefore avoid rasterized graphics as much as possible.
I am trying to import an svg file on to a matplotlib figure:
import matplotlib.pyplot as plt
earth = plt.imread('./gfx/earth.svg')
fig, ax = plt.subplots()
im = ax.imshow(earth)
plt.show()
This works with png perfectly. Can somebody tell me how to do it with svg or at least point my to proper documentation.
I know that a similar question has been asked (but not answered): here. Has anything changed since?
P.S. I know that I could just export a high resolution png and achieve a similar effect. This is not the solution I am looking for.
Here is the image I would like to import:
.
Maybe what you are looking for is svgutils
import svgutils.compose as sc
from IPython.display import SVG # /!\ note the 'SVG' function also in svgutils.compose
import numpy as np
# drawing a random figure on top of your SVG
fig, ax = plt.subplots(1, figsize=(4,4))
ax.plot(np.sin(np.linspace(0,2.*np.pi)), np.cos(np.linspace(0,2.*np.pi)), 'k--', lw=2.)
ax.plot(np.random.randn(20)*.3, np.random.randn(20)*.3, 'ro', label='random sampling')
ax.legend()
ax2 = plt.axes([.2, .2, .2, .2])
ax2.bar([0,1], [70,30])
plt.xticks([0.5,1.5], ['water ', ' ground'])
plt.yticks([0,50])
plt.title('ratio (%)')
fig.savefig('cover.svg', transparent=True)
# here starts the assembling using svgutils
sc.Figure("8cm", "8cm",
sc.Panel(sc.SVG("./Worldmap_northern.svg").scale(0.405).move(36,29)),
sc.Panel(sc.SVG("cover.svg"))
).save("compose.svg")
SVG('compose.svg')
Output:
to anyone ending up here in 2021...
I'd suggest having a look at the cairosvg package
(conda install -c conda-forge cairosvg or pip3 install cairosvg)
https://cairosvg.org/
import cairosvg
import matplotlib.pyplot as plt
from PIL import Image
from io import BytesIO
img_png = cairosvg.svg2png("... the content of the svg file ...")
img = Image.open(BytesIO(img_png))
plt.imshow(img)
SVG (Scalable Vector Graphics) is a vectorial format, which means the image is not composed of pixels, but instead of relative paths that can be scaled arbitrarily.
NumPy/Matplotlib, as numerics software, only really works with pixel graphics and cannot handle svg. I would suggest first converting the svg file to e.g. a png file by opening and saving it in software such as Inkscape (which is free). Then, open the exported png in Python.
Alternatively, use the wikimedia provided versions of the file in png format on the picture's information page (click on the download button to the right of the picture).
If you really believe you need the vectorial form, well, there is no way to do that. You can always superpose the matplotlib figure on to the figure manually (using the matplotlib Artist to draw on the plot canvas), or through some pycairo magic, and save that. But Matplotlib cannot work directly with svg content.