How would you render a map such as this one within Mathematica? (e.g. one with US states and Canadian provinces colourable separately?) http://upload.wikimedia.org/wikipedia/commons/archive/1/18/20071029031002%21North_America_map_coloured.svg
I've tried to import the SVG paths and build polygons (with an approach based on http://mathgis.blogspot.com/2009/11/make-us-county-thematic-map-using.html) but they look much less nice than the curves in the linked SVG. The built-in databases didn't appear to have shapes for US states and Canadian provinces: only countries.
Thanks!
PS: the aim of this is to be able to make choropleth maps for state/province data (i.e. to colour states/provinces according to some data related to that state/province)
You could use .kml or .kmz files to get a list of states/provinces and polygons for their outlines. For example for the USA you could use this file. To extract the polygons you could do something like this
usa = Import["http://code.google.com/apis/kml/documentation/us_states.kml",
"Data"];
transform[s_] := StringTrim[s, Whitespace ~~ "(" ~~ ___ ~~ ")"]
polygons = Thread[transform["PlacemarkNames" /. usa[[1]]] ->
("Geometry" /. usa[[1]])];
stateNames = polygons[[All, 1]];
Then polygons will be a list with elements "state name" -> Polygon[points]. The function transform is just a helper function to get the PlacemarkNames from the .kml file in the desired format (in this case stripping "(year)" off the end of the names).
Using these polygons you can then use FaceForm[] to colour the individual polygons. Suppose we have a list of data of the form "state" -> value, e.g.
data = Thread[regionNames -> RandomReal[{0, 1}, Length[regionNames]]];
Then we can create the map according to
colourf = ColorData["Temperature"];
element[value_, poly_] := GraphicsGroup[{EdgeForm[Black], FaceForm[colourf[value]], poly}]
Graphics[{element ### Transpose[regionNames /. {data, polygons}]}]
Which looks like
What about using some image processing on existing map images? This is just a prototype workflow. There are quite a few things to explore with data integrated from Wolfram]Alpha and image processing in Mathematica. You can play we these in more detail. I did not really try to use the population data and color the map accordingly, but I think it is possible. Function MorphologicalComponents[...] detects and indexes states regions between the borders.
map = WolframAlpha["Illinois", {{"Location:USStateData", 1}, "Image"}]
bmap = Binarize[map, .7]
dmap = ColorNegate#Dilation[ColorNegate#bmap, .75]
MorphologicalComponents[dmap] // Colorize
Another option to outline the states begins with using the GeoGraphics feature:
GeoGraphics[
{
EdgeForm[Black],
Polygon[CountryData["UnitedStates", "AdministrativeDivisions"]]
}
GeoBackground -> None,
GeoProjection -> "Mercator"
]
Related
Context
I have an merged geodataframe of 1). Postalcode areas and 2). total amount of deliveries within that postalcode area in the city of Groningen called results. The geodataframe includes geometry that include Polygons and Multiploygons visualizing different Postal code areas within the city.
I am new to GeoPandas and therefore I've tried different tutorials including this one from the geopandas official website wherein I got introduced into interactive Folium maps, which I really like. I was able to plot my geodataframe using result.explore(), which resulted in the following map
The problem
So far so good, but now I want to simply place an marker using the folium libarty with the goal to calculate the distance between the marker and the postalcode areas. After some looking on the internet I found out in the quickstart guild that you need to create an folium.Map, then you need folium.Choropleth for my geodataframe and folium.Marker and add them to the folium.Map.
m = folium.Map(location=[53.21917, 6.56667], zoom_start=15)
folium.Marker(
[53.210903, 6.598276],
popup="My marker"
).add_to(m)
folium.Choropleth(results, data=results, columns="Postcode", fill_color='OrRd', name="Postalcode areas").add_to(m)
folium.LayerControl().add_to(m)
m
But when try to run the above code I get the following error:
What is the (possible) best way?
Besides my failing code (which would be great if someone could help me out). I am curious if this is the way to do it (Folium map + marker + choropleth). Is it not possible to call geodataframe.explore() which results into the map in second picture and then just add an marker on the same map? I have the feeling that I am making it too difficult, there must be an better solution using Geopandas.
you have not provided the geometry. Have found postal districts of Netherlands and used that
explore() supports will draw a point as a marker with appropriate parameters
hence two layers,
one is postal areas coloured using number of deliveries
second is point, with distance to each area calculated
import geopandas as gpd
import shapely.geometry
import pandas as pd
import numpy as np
geo_url = "https://geodata.nationaalgeoregister.nl/cbsgebiedsindelingen/wfs?request=GetFeature&service=WFS&version=2.0.0&typeName=cbs_provincie_2017_gegeneraliseerd&outputFormat=json"
gdf = gpd.read_file(geo_url).assign(
deliveries=lambda d: np.random.randint(10**4, 10**6, len(d))
)
p = gpd.GeoSeries(shapely.geometry.Point(6.598276, 53.210903), crs="epsg:4386")
# calc distances to point
gdf["distance"] = gdf.distance(p.to_crs(gdf.crs).values[0])
# dataframe of flattened distances
dfp = pd.DataFrame(
[
"<br>".join(
[f"{a} - {b:.2f}" for a, b in gdf.loc[:, ["statcode", "distance"]].values]
)
],
columns=["info"],
)
# generate colored choropleth
m = gdf.explore(
column="deliveries", categorical=True, legend=False, height=400, width=400
)
# add marker with distances
gpd.GeoDataFrame(
geometry=p,
data=dfp,
).explore(m=m, marker_type="marker")
I've followed this tutorial:
https://towardsdatascience.com/creating-beautiful-maps-with-python-6e1aae54c55c
and the one this above was derived from.
They pass a list of edge colors to the plot_graph function
like so:
fig, ax = ox.plot_graph(gdf, node_size=0, bbox = (north, south, east, west),figsize=(height, width),
dpi = 96,bgcolor = bgcolor,
save = False, edge_color=roadColors,
edge_linewidth=roadWidths, edge_alpha=1)
I don't think they're assigned the way that the tutorial indicates.
On the github I found get_edge_colors_by_attr which seems to take attributes into account.
How are the colors assigned?
Specifically I am asking because I'd like to plot "highways" in different colors based on their openstreetmap tag.
How does osmnx.plot_graph determine which edges get which colors?
You can see how it does it here. Essentially, it either applies a single color to all edges or, if you passed it a list of colors, it assigns the first color in the list to the first edge in the graph, the second to the second, the third to the third, and so on.
Specifically I am asking because I'd like to plot "highways" in different colors based on their openstreetmap tag.
You can create a list of colors based on the edges' highway attribute values:
import osmnx as ox
G = ox.graph_from_place('Piedmont, California, USA', network_type='drive')
# assign colors to edges based on "highway" value
hwy_color = {'residential': 'gray',
'secondary': 'r',
'tertiary': 'y',
'tertiary_link': 'b',
'unclassified': 'm'}
edges = ox.graph_to_gdfs(G, nodes=False)['highway']
ec = edges.replace(hwy_color)
# plot graph using these colors
fig, ax = ox.plot_graph(G, edge_color=ec)
Also, you mentioned get_edge_colors_by_attr but note that per the docs the attribute must be numeric.
In the conv-nets model, I know how to visualize the filters, we can do itorch.image(model:get(1).weight)
But how could I efficiently visualize the output images after the convolution? especially those images in the second or third layer in a deep neural network?
Thanks.
Similarly to weight, you can use:
itorch.image(model:get(1).output)
To visualize the weights:
-- visualizing weights
n = nn.SpatialConvolution(1,64,16,16)
itorch.image(n.weight)
To visualize the feature maps:
-- initialize a simple conv layer
n = nn.SpatialConvolution(1,16,12,12)
-- push lena through net :)
res = n:forward(image.rgb2y(image.lena()))
-- res here is a 16x501x501 volume. We view it now as 16 separate sheets of size 1x501x501 using the :view function
res = res:view(res:size(1), 1, res:size(2), res:size(3))
itorch.image(res)
For more: https://github.com/torch/tutorials/blob/master/1_get_started.ipynb
I have several questions to do with handling some data in R:
I am using this statement: detailsTable <- read.table(file=commandArgs()[6], header=TRUE, col.names=c("a", "b", "c", "d", "e")) and it seems that the table is not being loaded correctly... but if I specify the path of the file I am loading excplicitly then all goes well. What am I doing wrong?
I plot the data contained in that table mentioned above. How do I save the plot (eg: plot.savePDF("plot.pdf")) to a PDF file?
How could I redirect the output of, for example, cor(detailsTable$a, detailsTable$b) to a file? and how do I write a simple string to a file. eg: "Correlation of the data: " + cor(...)
How do I plot the line of best fit on an existing plot?
All of this is in R.
Many thanks to anyone who can help,
ExtremeCoder
I plot the data contained in that table mentioned above. How do I save the plot (eg: plot.savePDF("plot.pdf")) to a PDF file?
pdf("filename.pdf")
plot(...)
dev.off()
How could I redirect the output of, for example, cor(detailsTable$a, detailsTable$b) to a file? and how do I write a simple string to a file. eg: "Correlation of the data: " + cor(...)
check the write.table manual page (?write.table)
How do I plot the line of best fit on an existing plot?
x <- 1:10
y <- 2 * x + runif(10)
plot (x, y, pch=20)
fit <- glm(y~x)
coefs <- coef(fit)
abline(coefs, lwd=2, col='red')
# Or also, without finding the coefficients
abline(fit, lwd=2, col='red')
You can redirect output using sink().
How to save the plot you're producing depends on which plotting system you're using. Assuming it's base graphics, you need to start a pdf graphics device, then plot to it.
pdf(file = "path/file.pdf", width = 5, height = 5)
...
#plotting commands here
...
dev.off()
I have a list of values each with latitude and longitude. I'm looking to create a translucent heatmap image to overlay on Google Maps. I know there are server side and flash based solutions already, but I want to build this in javascript using the canvas tag.
However, I can't seem to find a concise description of the algorithm used to turn coordinates and values into a heatmap. Can anyone provide or link to one?
Thanks.
The basic idea would be to create a grid and project every lat,lng coord to that grid. I would use a 2D array of ints.
The psuedo-code would be:
for each coord
cell = coord projected to grid
increment cell value
end
for 0 to # of passes
for each row
for each col
if grid[row,col] > 0 then
grid[row,col] += 1
increment_adjacent_cells(row, col)
end
end
end
end
So, the idea is that the higher the int value, the hotter that cell is. increment_adjacent_cells should increment the values in all 8 adjacent cells.
I have tried to solve this in javascript using the canvas element, here is my current result:
http://gist.github.com/346165
I have to fix the gaussian filter and the color mapping, because it doesn't give good results currently.
A faster way of building a heatmap could be to use a queue:
Pseudocode:
Add an element to queue (first in heatmap(x,y, val))
While (!queue.isEmpty())
{
elem = queue.pop()
queue.push(elem.x + 1, elem.y, val-1)
queue.push(elem.x - 1, elem.y, val-1)
queue.push(elem.x, elem.y + 1, val-1)
queue.push(elem.x, elem.y - 1, val-1)
}
This saves on tons of iterations!
Look at this project if you are looking for something that looks more like 'tv weather maps':
https://github.com/optimisme/javascript-temperatureMap