Solución:
Hay una mejor alternativa a partir de ahora, que es hacer un trazado fuera de línea en un div, en lugar de un html completo. Esta solución no implica ningún truco.
Si llamas:
plotly.offline.plot(data, filename="file.html")
Crea un archivo llamado file.html
y lo abre en su navegador web. Sin embargo, si lo hace:
plotly.offline.plot(data, include_plotlyjs=False, output_type="div")
la llamada devolverá una cadena con solo el div requerido para crear los datos, por ejemplo:
<div id="82072c0d-ba8d-4e86-b000-0892be065ca8" style="height: 100%; width: 100%;" class="plotly-graph-div"></div>
<script type="text/javascript">window.PLOTLYENV=window.PLOTLYENV || {};window.PLOTLYENV.BASE_URL="https://plot.ly";Plotly.newPlot("82072c0d-ba8d-4e86-b000-0892be065ca8",
[{"y": ..bunch of data..., "x": ..lots of data.., {"showlegend": true, "title": "the title", "xaxis": {"zeroline": true, "showline": true},
"yaxis": {"zeroline": true, "showline": true, "range": [0, 22.63852380952382]}}, {"linkText": "Export to plot.ly", "showLink": true})</script>
Observe cómo es solo una pequeña parte de un html que se supone que debe incrustar en una página más grande. Para eso utilizo un motor de plantilla estándar como Jinga2.
Con esto, puede crear una página html con varios gráficos organizados de la manera que desee, e incluso devolverlo como un respuesta del servidor a una llamada ajax, muy dulce.
Actualizar:
Recuerde que deberá incluir el archivo js plotly para que funcionen todos estos gráficos.
Podrías incluir
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
justo antes de poner el div que tienes. Si coloca este js en la parte inferior de la página, los gráficos no funcionará.
Opción 1: Utilice la funcionalidad fuera de línea de plotly en su Jupyter Notebook (supongo que está utilizando un Jupyter Notebook desde el enlace que proporciona). Simplemente puede guardar todo el cuaderno como un archivo HTML. Cuando hago esto, la única referencia externa es a JQuery; plotly.js se incluirá en el código fuente HTML.
opcion 2: La mejor manera es probablemente codificar directamente contra la biblioteca JavaScript de plotly. La documentación para esto se puede encontrar aquí: https://plot.ly/javascript/
Actualizar: Llamar a una función interna nunca ha sido una buena idea. Recomiendo utilizar el enfoque dado por @Fermin Silva. En las versiones más recientes, ahora también hay una función dedicada para esto: plotly.io.to_html
(ver https://plotly.com/python-api-reference/generated/plotly.io.to_html.html)
Opción Hacky 3 (versión original solo como referencia): si realmente desea continuar usando Python, puede usar algún truco para extraer el HTML que genera. Necesita alguna versión reciente de plotly (la probé con plotly.__version__ == '1.9.6'
). Ahora, puede usar una función interna para obtener el HTML generado:
from plotly.offline.offline import _plot_html
data_or_figure = [{"x": [1, 2, 3], "y": [3, 1, 6]}]
plot_html, plotdivid, width, height = _plot_html(
data_or_figure, False, "", True, '100%', 525)
print(plot_html)
Simplemente puede pegar la salida en algún lugar del cuerpo de su documento HTML. Solo asegúrese de incluir una referencia a la trama en la cabeza:
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
Alternativamente, también puede hacer referencia a la versión gráfica exacta que utilizó para generar el HTML o en línea la fuente JavaScript (que elimina cualquier dependencia externa; sin embargo, tenga en cuenta los aspectos legales).
Terminas con un código HTML como este:
<html>
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<!-- Output from the Python script above: -->
<div id="7979e646-13e6-4f44-8d32-d8effc3816df" style="height: 525; width: 100%;" class="plotly-graph-div"></div><script type="text/javascript">window.PLOTLYENV=window.PLOTLYENV || {};window.PLOTLYENV.BASE_URL="https://plot.ly";Plotly.newPlot("7979e646-13e6-4f44-8d32-d8effc3816df", [{"x": [1, 2, 3], "y": [3, 1, 6]}], {}, {"showLink": false, "linkText": ""})</script>
</body>
</html>
Nota: El guión bajo al principio del nombre de la función sugiere que _plot_html
no está destinado a ser llamado desde un código externo. Por lo que es probable que este código se rompa con futuras versiones de plotly.
Además de las otras respuestas, otra posible solución es utilizar to_json()
en la figura de la trama.
No es necesario un serializador JSON personalizado ni el uso de soluciones internas.
import plotly
# create a simple plot
bar = plotly.graph_objs.Bar(x=['giraffes', 'orangutans', 'monkeys'],
y=[20, 14, 23])
layout = plotly.graph_objs.Layout()
fig = plotly.graph_objs.Figure([bar], layout)
# convert it to JSON
fig_json = fig.to_json()
# a simple HTML template
template = """<html>
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div id='divPlotly'></div>
<script>
var plotly_data = {}
Plotly.react('divPlotly', plotly_data.data, plotly_data.layout);
</script>
</body>
</html>"""
# write the JSON to the HTML template
with open('new_plot.html', 'w') as f:
f.write(template.format(fig_json))