Saygın Doğu Saygın Doğu - 1 year ago 168
R Question

Heatmap on Zeppelin using Leaflet

I want to add a heatmap to a Zeppelin paragraph using Leaflet with R. I wrote a script in R Studio which works fine, but when I migrate to Zeppelin the heatmap is not showing. Here is my code in R Studio

map3 <- Leaflet$new()
map3$setView(c(29.7632836, -95.3632715), 10)

vector <- c( list(c(29.76,-95.36, 50)), list(c(29.77, -95.37, 50)), list(c(29.75,-95.39,50)))
#vector = toJSONArray2(na.omit(vector), json = F, names = F)

map3$addAssets(jshead = c(

map3$addAssets(jshead = c(""))
map3$setTemplate(afterScript = sprintf("
var addressPoints = %s
var heat = L.heatLayer(addressPoints).addTo(map)


My code in Zeppelin is almost identical. Only the input and the output method changes:


sparkcontext <- sparkR.init("local[4]","cvspark",sparkEnvir=list(spark.executor.memory="1g"))

positions <- sql("SELECT lat, long FROM my_table")
pos <- collect(positions)

map3 <- Leaflet$new()

map3$setView(c(39.93, 32.85))

vector <- c()
values1 <- pos[[1]]
values2 <- pos[[2]]
for (i in 1:length(values1))
vector <- c(vector, list(c(values1[i], values2[i], 1000)))


map3$addAssets(jshead = c(""))
map3$setTemplate(afterScript = sprintf("
var addressPoints = %s
var heat = L.heatLayer(addressPoints).addTo(map)

map3$print("map3", include_assets=TRUE, cdn=TRUE)

The following code shows the inputs are identical:


R Studio output:


Zeppelin output:


The problem here is
map3$print("map3", include_assets=TRUE, cdn=TRUE)
does not include the heatmap layer in its output. In order to show the map on Zeppelin, as far as I know, this method has to be called. The question is: How do we make the print method include the javascript code which enables the heatmap layer on the map.

Also I get the following error in Zeppelin. But I don't think it is relevant to this question:

Error in sparkR.sparkContext(master, appName, sparkHome, convert`NamedListToEnv(sparkEnvir), : JVM is not ready after 10 seconds

Answer Source

This code won't show the heatmap layer:

map3$print("map3", include_assets=TRUE, cdn=TRUE)

Use %angular interpreter and variable binding instead:

<link rel="stylesheet" href="" />
<script src="scripts/leaflet-heat.js"></script>

<input type="hidden" value="{{coordinates}}" id="coordinates_values">
<div id="map" style="height: 800px; width: 100%"></div>
<script type="text/javascript">
function initMap() {
    var map ='map').setView([39.95, 32.50], 10);

    L.tileLayer('http://{s}{z}/{x}/{y}.png', {
        attribution: 'Map data &copy; <a href="">OpenStreetMap</a> contributors',
        maxZoom: 12,
        minZoom: 3

    var geoMarkers = L.layerGroup().addTo(map);

    var el = angular.element($('#map').parent('.ng-scope'));

    console.log( $("#coordinates_values").val())
    var coordinates = $.parseJSON( $("#coordinates_values").val() );
    var heat = L.heatLayer( coordinates, {radius: 35}).addTo(map);

    angular.element(el).ready(function() {
        window.locationWatcher = el.scope().compiledScope.$watch('locations', function(newValue, oldValue) {
            // geoMarkers.clearLayers(); -- if you want to only show new data clear the layer first
            angular.forEach(newValue, function(tweet) {
                var marker = L.marker([, tweet.loc.lon ])
                  .bindPopup(tweet.user + ": " + tweet.tweet)

if (window.locationWatcher) {
    // clear existing watcher otherwise we'll have duplicates

// ensure we only load the script once, seems to cause issues otherwise
if (window.L) {
} else {
    console.log('Loading Leaflet library');
    var sc = document.createElement('script');
    sc.type = 'text/javascript';
    sc.src = '';
    sc.onload = initMap;
    sc.onerror = function(err) { alert(err); }