Display multiple mpld3 exports on a single HTML page - python

I've found the mpld3 package to be brilliant for exporting a matplolib plot to HTML and displaying this via a flask app.
Each export comes with a lot of JS which seems unnecessary duplication if you want to display multiple plots within a single page. However I'm not well enough versed in JS to extract the relevant components and then loop through them. The .fig_to_dict method gives the necessary JSON to display each chart but then I'm left wondering what JS/ template work is needed to display each chart in turn.
I considered just stacking each plot into a single big figure but I'd like to layout the charts in separate DIVs and so this isn't the right solution.
I think I can see what the JS is doing to display them but I don't have enough knowledge to modify the functions to suit the purpose.
I haven't included code as I'm expecting this only to be relevant to someone with mpld3 experience but can supply some sample code if needed.
Sample HTML output for mpld3.fig_to_html(fig, template_type="simple"):
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="http://mpld3.github.io/js/mpld3.v0.1.js"></script>
<style>
</style>
<div id="fig136845463888164451663379"></div>
<script type="text/javascript">
var spec136845463888164451663379 = { <snip JSON code> };
var fig136845463888164451663379 = mpld3.draw_figure("fig136845463888164451663379", spec136845463888164451663379);
</script>
I'd thought it would be as simple as linking the two core scripts from the template header and then creating a new script for each JSON export. But that hasn't worked for me.

You're half-way there with your answer. I think what you want to do is something like this, which will embed three figures on the page:
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="http://mpld3.github.io/js/mpld3.v0.1.js"></script>
<style>
</style>
<div id="fig01"></div>
<div id="fig02"></div>
<div id="fig03"></div>
<script type="text/javascript">
var json01 = { <snip JSON code> };
var json02 = { <snip JSON code> };
var json03 = { <snip JSON code> };
mpld3.draw_figure("fig01", json01);
mpld3.draw_figure("fig02", json02);
mpld3.draw_figure("fig03", json03);
</script>
The json code for each figure can be created in Python by running
import json
# ... create matplotlib figure
json01 = json.dumps(mpld3.fig_to_dict(fig))
Embed this string at the appropriate place in the HTML document you're creating, and you should be good to go. I hope that helps!

Note that since jakevdp's answer was posted mpld3 has had a new release. As of today (September 2014) the mpld3 include has to be:
<script type="text/javascript" src="http://mpld3.github.io/js/mpld3.v0.2.js"></script>

Related

Plotly + ajax - plot is not rendered

I have a django based web application; and I am using the Python wrappers of plotly to generate plots. When I try to use "ajax style" to fetch only the plot into a <div> </div> with a javascript call no plot is rendered. My situation is as follows:
<head>
<script>
async function generate_plot() {
const url = "/path/to/plot/generator/";
let response = await fetch(url);
let data = await response.text();
let element = document.getElementById('plot_div');
element.innerHTML = data;
}
</script>
</head>
<body>
<div id="plot_div"> </div>
...
</body>
At the /path/to/plot/generator/ endpoint there is a python function which looks like:
def plot_generator(request):
...
return plotly.offline.plot(fig, include_plotlyjs=False, output_type="div")
I am quite certain this is basically sound, because when I manually paste the return value from plot_generator() into <div id="plot_div"></div> the plot is displayed correctly, and also If I let the plot_generator() just return a dummy text like: This should have been a plot - the text is correctly displayed. But the plotly plot is not displayed in any way - the Firefox debug console shows no warnings/errors/anything ...
Something trivially wrong?
Update: When looking in the firefox console the plotly generated content seems to have arrived correctly in the browser/DOM.

Only upload file names and metadata

Is it possible to have a upload box on a site where a user can drag in a folder of files but instead of the entire folder being uploaded you can just grab the file names and metadata?
Not complete, but probably a good start...
This would be possible with dropzone.js, by setting the autoProcessQueue option to false. Then you can drop files/folders via the GUI, without them actually uploading, but still access the file object in javascript to get the metadata.
See this answer for more information on how to add a manual button to eventually start processing this queue if you wish. Regardless of whether you process that queue or not, you can use the addedfile event to manually inspect the file objects.
A really basic example, with the scripts loaded from a CDN, would look like:
<html>
<head>
<title> Dropzone</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.0/dropzone.css" integrity="sha256-0Z6mOrdLEtgqvj7tidYQnCYWG3G2GAIpatAWKhDx+VM=" crossorigin="anonymous" />
</head>
<body>
<div>
<form method='POST'
enctype="multipart/form-data"
class="dropzone"
id="my-awesome-dropzone"></form>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.0/dropzone.js" integrity="sha256-NLit4Z57jz8npRHkopjfr68hSZY1x/ruN0T8kf68xq4=" crossorigin="anonymous"></script>
<script type='text/javascript'>
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone("form#my-awesome-dropzone",
{ url: "/upload",
autoProcessQueue: false,
});
myDropzone.on("addedfile", function(file) {
// runs for every file dropped
console.log(file.name, file.fullPath, file.lastModified, file.size);
});
</script>
</body>
</html>
Dropping a single file with the above code outputs something like:
views.py undefined 1567770276854 1604
You can drop an entire folder, and every file recursively will appear, including file.fullPath for each:
models.py stack/models.py 1566159281216 1974
serializers.py stack/serializers.py 1565978398499 309
...
You could instead console.log(file) to inspect that object further (in your browser's dev tools console) to see the other available metadata.
To get this data to the backend you could use the fetch API or a similar AJAX post function. You may wish to add all the info to an array, then post this to the backend at once using another event handler tied to an "Upload metadata!" button.

Update Value dynamically using repeated Ajax calls from DJango template

I wanted to show my sound sensor readings from a django site (original code as posted in the link). Now as per the situation 2 of the accepted answer, I wanted to make a Javascript function which repeatedly calls the ajax_data function from views template.
But it seems that no repeated calls are being made. And no update in reading reflects either.
My django template till now:
<!doctype html>
<html>
<head>
<title>Noise measurement site</title>
<script src="http://code.jquery.com/jquery-3.0.0.js"
integrity="sha256-jrPLZ+8vDxt2FnE1zvZXCkCcebI/C8Dt5xyaQBjxQIo="
crossorigin="anonymous"></script>
<script language="javascript" type="text/javascript">
function updateValue() {
$.ajax({
url:"D:/Python programs/django_projects/Noise_Measurement/noise_m/views.py/ajax_data/",
//success: updateValue(), for experimenting with a recursive call...
});
}
$(document).ready(function(){
var v = setInterval(updateValue,2000);
});
</script>
</head>
<body>
<p>Hello there</p>
<p>Present noise level : {{noise_level}} dB</p>
</body>
</html>
(I have mentioned rest of the code in my previously asked question. I have read some of the answers on the platform but I'm not getting much results.)
Update
Sorry I made a mistake. I made slight changes in the code and posted output without that only. Now I have made the exact changes as in the previous part. But output is not sorted out yet. (Thanks to comment by CumminUp07)
** Own answer on own question **
Oh sorry, actually it was a misunderstanding of the syntax from my side.
I was first supposed to create method in views.py, which will send the reading from the module taking it. Then for that method, I had to assign an url using path(), in a fashion like:
path('read', views.data_update1, name='readings'),
Then the ajax request was supposed to be made to read link:
$.ajax({
url: "read",
dataType: "json",
contentType: "application/json",
success: function(r) { ... }
});
Then this method is conveniently called using setInterval method.
But finally at the line, the {{ }} didn't help, so the div where the value was to be displayed was assigned an id, whose value was updated on each call of the method.

Embedding Python Game Into HTML Using Skulpt

I have written a game in Python using the PyGame library that I am trying to embed into an HTML page to allow me to play in a web browser.
I am attempting to do this using the JavaScript library Skulpt. I have attached a test script below that successfully outputs the print statement below.
skulpt.html
<html>
<head>
<script src="assets/skulpt/skulpt.js" type="text/javascript"></script>
</head>
<body>
<textarea id="pythonCode">
print "I am python."
</textarea><br />
<pre id="output"></pre>
<script type="text/javascript">
function outf(text) {
var mypre = document.getElementById("output");
mypre.innerHTML = mypre.innerHTML + text;
}
var code = document.getElementById("pythonCode").value;
Sk.configure({output:outf});
eval(Sk.importMainWithBody("<stdin>",false,code));
</script>
</body>
</html>
Output of skulpt.html:
The issue that I am having is that when I use my game code instead of the simple print statement shown above it produces the error seen below;
I have included all relevant images to my web servers' directory at the correct path. I am unsure of why this error is being produced. Any help would be much appreciated, thanks!
Also, here is the attached Python game code (and a live demo of the error):
http://nicolasward.com/portfolio/skulpt.html
You have a lot of indentation on line 1 -> remember, in python, indentation always matters. Take away all those spaces/tabs on the first line and it should run.

Python Improperly Formatting AdSense code for GAE app?`

I have an AdSense ad embedding into the page http://mostpopnews.appspot.com/ (on the right most column / blank space) that's generated (along with the rest of the html by Python code used in GAE. It's been about 4 days since I created and embedded the ad script into the site, but the ad status has not changed from "New" to "Active". I am not sure why this is the case, as I have other blogs which convert to Active very quickly. Possibly because the site has not been indexed yet? My main hypothesis is that the Python code used to write the AdSense script is screwing something up with the HTML formatting that I can't see. Any ideas/
Python code for writing adsense script:
MAIN_PAGE_HTML = MAIN_PAGE_HTML + '''
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9089661734099673";
/* Top News */
google_ad_slot = "3468761149";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
'''
The source code of the webpage shows:
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9089661734099673";
/* Top News */
google_ad_slot = "3468761149";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>

Categories