Saving interactive Matplotlib figures
This would be a great feature, but AFAIK it isn't implemented in Matplotlib and likely would be difficult to implement yourself due to the way figures are stored.
I'd suggest either (a) separate processing the data from generating the figure (which saves data with a unique name) and write a figure generating script (loading a specified file of the saved data) and editing as you see fit or (b) save as PDF/SVG/PostScript format and edit in some fancy figure editor like Adobe Illustrator (or Inkscape).
EDIT post Fall 2012: As others pointed out below (though mentioning here as this is the accepted answer), Matplotlib since version 1.2 allowed you to pickle figures. As the release notes state, it is an experimental feature and does not support saving a figure in one matplotlib version and opening in another. It's also generally unsecure to restore a pickle from an untrusted source.
For sharing/later editing plots (that require significant data processing first and may need to be tweaked months later say during peer review for a scientific publication), I still recommend the workflow of (1) have a data processing script that before generating a plot saves the processed data (that goes into your plot) into a file, and (2) have a separate plot generation script (that you adjust as necessary) to recreate the plot. This way for each plot you can quickly run a script and re-generate it (and quickly copy over your plot settings with new data). That said, pickling a figure could be convenient for short term/interactive/exploratory data analysis.
Saving interactive series on matplotlib figures (html)
It is not possible to maintain the matplotlib.widget
interactivity in an html file generated by mpld3
. This is because the javascript generated by mpld3
runs client-side and cannot access the Python kernel that generated it.
You can achieve something like the matplotlib
interactivity in an html version using the Static Interactive Widgets for IPython Notebooks approach.
Save 3D Matplot as interactive HTML
As far as I'm aware, Matplotlib is not able to generate 3D html plot.
Moreover, what you tried above is wrong. That error message is telling you that Plotly's to_html
only works with Plotly's Figure
. So mixing Plotly and Matplotlib is not going to work. You need to create a Plotly figure.
Also, I don't think that Plotly exposes something similar to Matplotlib's plot_trisurf
. However, it exposes go.Mesh
that allows us to achieve the same result.
The recipe:
- Generate your numerical data.
- Create a triangulation. We will use Matplotlib's
Triangulation
class for this part. - Create the Plotly figure and add the surface.
- Export the figure to html.
Here I'm going to post an example to guide you:
import numpy as np
import matplotlib.tri as mtri
import plotly.graph_objects as go
### DATA GENERATION
# Make parameter spaces radii and angles.
n_angles = 36
n_radii = 8
min_radius = 0.25
radii = np.linspace(min_radius, 0.95, n_radii)
angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False)
angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)
angles[:, 1::2] += np.pi/n_angles
# Map radius, angle pairs to x, y, z points.
x = (radii*np.cos(angles)).flatten()
y = (radii*np.sin(angles)).flatten()
z = (np.cos(radii)*np.cos(3*angles)).flatten()
### TRIANGULATION
# Create the Triangulation; no triangles so Delaunay triangulation created.
triang = mtri.Triangulation(x, y)
# Mask off unwanted triangles.
xmid = x[triang.triangles].mean(axis=1)
ymid = y[triang.triangles].mean(axis=1)
mask = xmid**2 + ymid**2 < min_radius**2
triangles = triang.triangles[~mask]
### PLOT
fig = go.Figure(data=[
# go.Mesh allows to provide the triangulation
go.Mesh3d(
x=x, y=y, z=z,
colorbar_title='z',
colorscale="aggrnyl",
# Intensity of each vertex, which will be interpolated and color-coded
intensity =z,
# i, j and k give the vertices of triangles
i = triangles[:, 0],
j = triangles[:, 1],
k = triangles[:, 2],
showscale=True
)
])
fig.show()
### EXPORT TO HTML
# Please, execute `help(fig.write_html)` to learn about all the
# available keyword arguments to control the output
fig.write_html("test.html", include_plotlyjs=True, full_html=True)
Dynamically serving a matplotlib image to the web using python
You should
- first write to a cStringIO object
- then write the HTTP header
- then write the content of the cStringIO to stdout
Thus, if an error in savefig
occured, you could still return something else, even another header. Some errors won't be recognized earlier, e.g., some problems with texts, too large image dimensions etc.
You need to tell savefig
where to write the output. You can do:
format = "png"
sio = cStringIO.StringIO()
pyplot.savefig(sio, format=format)
print "Content-Type: image/%s\n" % format
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) # Needed this on windows, IIS
sys.stdout.write(sio.getvalue())
If you want to embed the image into HTML:
print "Content-Type: text/html\n"
print """<html><body>
...a bunch of text and html here...
<img src="data:image/png;base64,%s"/>
...more text and html...
</body></html>""" % sio.getvalue().encode("base64").strip()
how to edit the saved graph by matplotlib?
As said by Arjun Muraleedharan, once you save your plot in Matplotlib, you will not be able to modify it.
However, if your problem is with the axes overlapping in the image, then try plt.tight_layout()
. Call this just before your plt.show()
in your code, assuming you did import matplotlib.pyplot as plt
.
What it does is it prevents any overlapping of anything in your plots and makes everything look a lot neater, which (I think) is what you are looking for.
Related Topics
Is the List of Python Reserved Words and Builtins Available in a Library
How to Sort Alpha Numeric Set in Python
Using Headers with the Python Requests Library's Get Method
How to Parse a Time String Containing Milliseconds in It with Python
Authentication Plugin 'Caching_Sha2_Password' Is Not Supported
Can Modules Have Properties the Same Way That Objects Can
What's the Difference Between "Pip Install" and "Python -M Pip Install"
How to Use a Socks 4/5 Proxy with Urllib2
How to Return 0 with Divide by Zero
Replacing Numpy Elements If Condition Is Met
Putting an If-Elif-Else Statement on One Line
How to Get Value Counts for Multiple Columns at Once in Pandas Dataframe
Python Urllib2, Basic Http Authentication, and Tr.Im
Alternative Way to Split a List into Groups of N
Pip Freeze Creates Some Weird Path Instead of the Package Version