I ran the test code below which is near identical to yours.
import arcpy
mxd = arcpy.mapping.MapDocument(r"C:\temp\test.mxd")
for elm in arcpy.mapping.ListLayoutElements(mxd, "MAPSURROUND_ELEMENT"):
print elm.name
if elm.name == "North Arrow":
print elm.style
elm.style = "ESRI North 1"
mxd.save()
del mxd
What you will notice is that the print elm.style
reports:
Traceback (most recent call last): File "C:/temp/test5.py", line 7,
in
print elm.style AttributeError: 'MapSurroundElement' object has no attribute 'style'
So the reason your code achieves nothing is that it simply sets a Python variable called elm.style
to the value "ESRI North 1" rather than setting a non-existent property called style
of an ArcPy MapSurroundElement object.
I do not know of a way to change the style of a North Arrow using ArcPy so, if no one else does either, then I recommend that someone create an ArcGIS Idea to have ArcPy provided with a writable property on its MapSurroundElement objects.
Here's my approach for making a more generalized heat map in Leaflet using R. This approach uses contourLines
, like the previously mentioned blog post, but I use lapply
to iterate over all the results and convert them to general polygons. In the previous example it's up to the user to individually plot each polygon, so I would call this "more generalized" (at least this is the generalization I wanted when I read the blog post!).
## INITIALIZE
library("leaflet")
library("data.table")
library("sp")
library("rgdal")
# library("maptools")
library("KernSmooth")
library("magrittr")
## LOAD DATA
## Also, clean up variable names, and convert dates
inurl <- "https://data.cityofchicago.org/api/views/22s8-eq8h/rows.csv?accessType=DOWNLOAD"
dat <- data.table::fread(inurl) %>%
setnames(., tolower(colnames(.))) %>%
setnames(., gsub(" ", "_", colnames(.))) %>%
.[!is.na(longitude)] %>%
.[ , date := as.IDate(date, "%m/%d/%Y")] %>%
.[]
## MAKE CONTOUR LINES
## Note, bandwidth choice is based on MASS::bandwidth.nrd()
kde <- bkde2D(dat[ , list(longitude, latitude)],
bandwidth=c(.0045, .0068), gridsize = c(100,100))
CL <- contourLines(kde$x1 , kde$x2 , kde$fhat)
## EXTRACT CONTOUR LINE LEVELS
LEVS <- as.factor(sapply(CL, `[[`, "level"))
NLEV <- length(levels(LEVS))
## CONVERT CONTOUR LINES TO POLYGONS
pgons <- lapply(1:length(CL), function(i)
Polygons(list(Polygon(cbind(CL[[i]]$x, CL[[i]]$y))), ID=i))
spgons = SpatialPolygons(pgons)
## Leaflet map with polygons
leaflet(spgons) %>% addTiles() %>%
addPolygons(color = heat.colors(NLEV, NULL)[LEVS])
Here's what you'll have at this point:
## Leaflet map with points and polygons
## Note, this shows some problems with the KDE, in my opinion...
## For example there seems to be a hot spot at the intersection of Mayfield and
## Fillmore, but it's not getting picked up. Maybe a smaller bw is a good idea?
leaflet(spgons) %>% addTiles() %>%
addPolygons(color = heat.colors(NLEV, NULL)[LEVS]) %>%
addCircles(lng = dat$longitude, lat = dat$latitude,
radius = .5, opacity = .2, col = "blue")
And this is what the heat map with points would look like:
Here's an area that suggests to me that I need to tune some parameters or perhaps use a different kernel:
## Leaflet map with polygons, using Spatial Data Frame
## Initially I thought that the data frame structure was necessary
## This seems to give the same results, but maybe there are some
## advantages to using the data.frame, e.g. for adding more columns
spgonsdf = SpatialPolygonsDataFrame(Sr = spgons,
data = data.frame(level = LEVS),
match.ID = TRUE)
leaflet() %>% addTiles() %>%
addPolygons(data = spgonsdf,
color = heat.colors(NLEV, NULL)[spgonsdf@data$level])
Best Answer
I found this paper from the Journal of Statistical Software (https://www.jstatsoft.org/article/view/v019c01/v19c01.pdf)
It provides the following function:
I got it to work doing this:
library(GISTools) data(newhaven) plot(blocks) xy = c(530000,160000)#use locator() to get the x,y values for arrow placement northarrow(loc = xy, size = 10000)#finding the correct size value is a guessing game
You can fiddle with the polygon commands, but this one looks pretty nice. --Also there is another arrow available in the prettymapr package. Cheers, Lewis