Adding labels to altair choropleth maps - label

Is there a way to add labels to the state maps? For example, to have the percentages directly on the individual states instead of only being able to see them via the tool tip?
I'm not sure if Altair has this option or if I will need to look into other packages (plotly, folium etc.) and do some layering to get those results.
import altair as alt
from vega_datasets import data
states = alt.topo_feature(data.us_10m.url, 'states')
variable_list = ['Percentage', 'State Name', 'state_id']
alt.Chart(states).mark_geoshape(stroke='white', width=0.01).encode(
color=alt.Color('Percentage:Q', title='Positive NFB', legend=alt.Legend(format=".0%"), scale=alt.Scale(scheme='yellowgreenblue', domain=[0, 1])),
tooltip=['State Name:N', alt.Tooltip('Percentage:Q', format='.0%')]).properties(title="Percentage of People in Households with Positive NFB"
).transform_lookup(
lookup='id',
from_=alt.LookupData(states_positive_NFB, 'state_id', variable_list)
).properties(
width=500,
height=300
).project(
type='albersUsa'
)

Altair has no built-in features for displaying labels on geographic regions. That said, if you have a dataframe with columns containing latitudes, longitudes, and text that you would like to display, you can do so with a mark_text() and latitude/longitude encodings; you can find an example of this in Altair's documentation: https://altair-viz.github.io/gallery/london_tube.html
If what you want is a visualization tool that has built-in functionality for computing centroids of geographic regions and drawing labels at those points, Altair is probably not what you're looking for.

Related

An existing vega-lite map suddenly seems very zoomed-in - what is happening?

I have a map with an older topojson format that once worked with Vega-Lite. Now we only see a purple square in this editor gist.
I've rebuilt the map with the same code but updated topojson in the vega editor and saved as a gist here.
With the new vega release, it seems like I need my topojson files to be formatted differently, with the arcs first, like the mapshaper.org export output. Why is this? It's broken several existing web maps, and took me a few hours to figure out. Seems like I can fix it with a workflow change, but I am curious.
Topojson data follows the left-hand rule for projected data (clockwise orientation for outer rings and counter- clockwise for interior rings), where the data in your topojson file is structured according the right-hand rule (counter-clockwise for outer rings and clockwise for interior rings). The order of your polygons seems negligible, but it defines which part is ‘inside’ and ‘outside’ the polgygons.
You can do two things:
Do not use a geographic projection, but the cartesian-like identity projection.
Force your source data into the right order.
Example for 1:
"projection": {"type": "identity", "reflectY": true},
see Vega Editor
Example for 2:
Use MapShaper or Python to force your data in the right order. Here an example using Python
import topojson as tp
import geopandas as gpd
gdf = gpd.read_file('https://raw.githubusercontent.com/nycehs/NeighborhoodReports/master/visualizations/json/UHF42.topo_old.json')
tp.Topology(gdf).to_json('UHF42.topo_new.json')
see Vega Editor
I wrote a bit about it before for Altair and Python Topojson
https://mattijn.github.io/topojson/example/settings-tuning.html#winding_order
https://altair-viz.github.io/user_guide/data.html#winding-order
And Mike Bostock for D3
https://bl.ocks.org/mbostock/a7bdfeb041e850799a8d3dce4d8c50c8

trellis layered plots in altair/Vega-Lite

I would like to compare multiple conditions of an altair (ultimately vega-lite) layered plot. The perfect solution would be to facet/trellis the plot so I can see the different conditions side by side. Unfortunately I cannot figure out how to give the command to plot the different conditions.
Here is my attempt to implement my idea based on the example for layered plots:
(https://github.com/ellisonbg/altair/blob/master/altair/notebooks/07-LayeredCharts.ipynb)
import pandas as pd
import numpy as np
data = pd.DataFrame({'x':np.random.rand(10), 'y':np.random.rand(10), 'z':['a', 'b']*5})
chart = LayeredChart(data)
chart += Chart().mark_line().encode(x='x:Q', y='y:Q', column='z:Q')
chart += Chart().mark_point().encode(x='x:Q', y='y:Q', column='z:Q')
chart
When compared with the example I added the column 'z' with the two conditions, and the two column statements in the Chart definitions.
This solution generates seemingly good Vega-lite code, but no plot. Alternatively I tried "chart = LayeredChart(data).encode(column='z:Q')" but I then got the error 'LayeredChart' object has no attribute 'encode'
I am wondering whether it is possible to facet (trellis) layered plots at all and whether it will be possible in future Vega-Lite releases.
I am using jupyter with Anaconda
Layering is only experimentally supported in the current release of Vega-Lite and Altair, and I believe you've hit one of the unsupported aspects. This should be addressed in the Vega-Lite 2.0 release (and associated Altair release) later this spring.

Using ONS maps with D3

I'm sorry this is probably a very basic issue, but I just can't seem to figure it out.
I wanted to map some data using D3.js and the map shape I wanted to use is provided by the UK's Office for National Statistics. I managed to get their geojson data to display, but as soon as I try to do anything with scaling, transforms, topojson, I've been a complete failure.
I've been through many, many, different approaches and I think it's something about the map data that is causing the issue. If I open the shape files in Mapshaper it looks perfect. If I export as geo or topojson and re-import, it looks perfect. If I try to run geo2svg on the geojson export it produces a lot of data, but nothing visible. If I try to import the original shape file into mapstarter.com it produces a flat line. And if I put the topojson into the D3 v4 bounding example I end up with a load of random triangles.
So, can someone show me how do you get ONS mapping data such as http://geoportal.statistics.gov.uk/datasets/1bc1e6a77cdd4b3a9a0458b64af1ade4_3 to display in a d3 example such as https://bl.ocks.org/iamkevinv/0a24e9126cd2fa6b283c6f2d774b69a2?
Thanks
The data that you have linked to is projected. Mapshaper supports projected data, but using d3.geoProjection with projected data will result in no data being displayed in most situations. You need to ensure your data is in lat long pairs for proper display with a d3.geoProjection.
Luckily, in Mapshaper you can reproject your data. Copy all the files of the shapefile into mapshaper, and in the console change the projection to wgs84 (unprojecting your data):
proj wgs84
This data is now easily displayed and manipulated using a d3.geoProjection. Here is an example using the data that you referenced. Also a screenshot:
Lastly: It is possible to display projected data as well, but this is much less common.

D3 visualization to create building / campus map

How do I create a building/school Map which I can zoom and get context information for each classroom using D3.
I have read examples of how to create Zoomable Geo Maps http://bl.ocks.org/mbostock/2206590 , but in the code, it uses the TopoJSON (or GeoJSON) format of the US states.
How do I get the GeoJSON file for a school building?
Thanks,
Raj.
Hard core geojson
There are online geojson editors, such geojson.io. You can find your building, map it, add properties such rooms name, then save it as geojson or as topojson file.
Note that geojson.io doesn't allow an infinite zoom, so your drawing may be quite approximative.
In your D3js code, you will have to autofocus on your json data (shape). A convenient working example is explain in the 2nd half of this answer, the D3js call and Focus sections.
Witty SVG
Designing your building as an SVG / XML file using Inkscape or some other vector editor would be a bit longer to do, but will end up into better end results. You then use d3.xml(http://yourwebsite.org/file.xml, function(data){ ... }). I have, unfortunately, too few expertise in this direction, but it's the way I would go for if quality is requested at that level.

Interactive Heatmap / Matrix Visualization

I would like to display on a webpage a heatmap (matrix) that I generate in R.
The matrix I have looks like this, but in my case the size is 300x300.
Basically I am looking for an interactive clustering, which would look like this :
http://online.wsj.com/article/SB125993225142676615.html#articleTabs%3Dinteractive
http://mbostock.github.com/protovis/ex/matrix.html
I would like to be able to clic on a branch which would then highlight the selected group/text, and fade out the rest of the matrix.
I have had a look around and cannot find much. I don't even know what language I should use for this ? JSON, Flash, HTML5, javascript, google charts ?
Any comments and advices would be extremely appreciated here.
Thanks.
I think that InCHlib - Interactive Cluster Heatmap library could be the solution.
Available from http://openscreen.cz/software/inchlib.
Google Visualization provides this heatmap option:
http://informatics.systemsbiology.net/visualizations/heatmap/bioheatmap.html
There's also this project that adapted it for more advanced uses and actually includes mouse-overs and tool-tips, as well as line magnification:
http://code.google.com/p/visquick/
You may also want to take a look at jQuery Flot, but be warned that WSJ uses a super expensive company called Tableau for data visualization and you are unlikely to find that level of visualization eye candy in an open source or free to use package.
Unfortunately, I had the same requirement. To create a Clustergram (Heatmap + Dendrogram) for a hierarchical clustering results.
There is no direct solution for this. I used ProtovisGWT (Choosel) to create dendrogram and heatmap seperatley and later combnied them.
If you just want js library you can use just protovis or d3.js to achieve this.
I would recommend using JavaScript for this task. Save your heatmap as SVG in R
svg("mymap.svg")
heatmap(...)
dev.off()
And then embed it into an HTML document as object
<object id="test-svg" width="800" height="600"
type="image/svg+xml" data="test.svg"></object>
Now, you can use JavaScript or ECMAScript to do all kinds of manipulations. I recommend to read one of the various online tutorials on this topic. E.g., you could get started with this one: http://www.petercollingridge.co.uk/data-visualisation/using-javascript-control-svg
Treemap of D3.js solves this beautifully. See here
http://mbostock.github.io/d3/talk/20111018/treemap.html
You could try http://amp.pharm.mssm.edu/clustergrammer/ . It is not written in R, but you can make an interactive clustergram by uploading a matrix file in tab-separated format and you will be returned an interactive (reorderable, searchable, filterable, etc) and shareable web-based visualization
D3heatmap provides interactive heatmaps with dendrograms in R based on the heatmap and heatmap.2 interfaces. It includes single row and column selection but does not currently allow selection of dendrogram branches.

Resources