Dear Stata Community,
I would like to share calligram, a new community-contributed command for making word clouds in Stata. It started as my earlier wordcloud2 command and has grown into a different package, hence the new name. It is not on SSC yet; it can be installed from GitHub:
It requires Stata 17 or newer. Nothing else needs to be installed: the layout engine is written in Java and runs on the Java that comes with Stata.
What it does
calligram reads a string variable of free text (for example open-ended survey answers), cleans and counts the words, and writes an interactive HTML page that works offline, plus, optionally, a PNG, JPG or SVG picture. Words are packed by the shape of their letters, so they never overlap. Some of the features:
- shapes: nine built-in shapes, any black-on-white picture (including a Stata graph you export), or a shape given by coordinates
- maps: with a Stata-format shapefile (as made by spshape2dta) and each city's latitude and longitude, every word is placed inside its own area; near keeps it close to its real location
- text handling for survey data: stopwords in English, French, Spanish and Portuguese (and your own list for any language), plurals merged with singulars, two-word phrases, weights, if/in, by() groups, and words you have already counted
- colour with meaning: colorby() colours words by the average of a variable, or by the group each word is most typical of (with a significance test)
- other writing systems: Arabic, Hebrew, Urdu, Hindi, Bengali, Tamil, Thai, Chinese, Japanese, Korean and more; Urdu can be drawn in Nastaliq with a bundled font
- saving() keeps every word with its count, size, position and colour as a dataset
A few examples, all using the example data copied by net get:
1. Inaugural addresses in a heart
2. Two-word phrases, with the words coloured by the century they are most typical of
phrases finds pairs such as "united states" and "fellow citizens" and lists them in the Results window. Grey words are not clearly more typical of any one century.
3. A world map: every city inside its own country, near its real location, sized by population
Places too small to hold a name at this scale are listed in the Results window.
4. Survey weights and the results as a dataset
Weights work as usual, for example calligram [aweight = w], textvar(response).
5. Customer comments in Urdu, drawn in Nastaliq
The attached pictures were written by calligram itself with image(). The interactive version of every example (search, hover for counts, zoom and pan on the maps, click the key to hide a group) can be opened here:
https://fahad-mirza.github.io/calligram_Stata/
The full guide and the source code are at https://github.com/fahad-mirza/calligram_Stata. calligram_gallery.do, copied by net get, builds all of the examples.
This is a beta release, so I would be grateful for any feedback, bug reports or suggestions, either here or as an issue on GitHub. When reporting a problem, the Stata version, the operating system, the output of which calligram, and the command with its output help a lot.
Best wishes,
Fahad Mirza
Examples:

The Shape of a Heart

I would like to share calligram, a new community-contributed command for making word clouds in Stata. It started as my earlier wordcloud2 command and has grown into a different package, hence the new name. It is not on SSC yet; it can be installed from GitHub:
Code:
net install calligram, from("https://raw.githubusercontent.com/fahad-mirza/calligram_Stata/main/") replace
net get calligram, from("https://raw.githubusercontent.com/fahad-mirza/calligram_Stata/main/") // example data
help calligram
What it does
calligram reads a string variable of free text (for example open-ended survey answers), cleans and counts the words, and writes an interactive HTML page that works offline, plus, optionally, a PNG, JPG or SVG picture. Words are packed by the shape of their letters, so they never overlap. Some of the features:
- shapes: nine built-in shapes, any black-on-white picture (including a Stata graph you export), or a shape given by coordinates
- maps: with a Stata-format shapefile (as made by spshape2dta) and each city's latitude and longitude, every word is placed inside its own area; near keeps it close to its real location
- text handling for survey data: stopwords in English, French, Spanish and Portuguese (and your own list for any language), plurals merged with singulars, two-word phrases, weights, if/in, by() groups, and words you have already counted
- colour with meaning: colorby() colours words by the average of a variable, or by the group each word is most typical of (with a significance test)
- other writing systems: Arabic, Hebrew, Urdu, Hindi, Bengali, Tamil, Thai, Chinese, Japanese, Korean and more; Urdu can be drawn in Nastaliq with a bundled font
- saving() keeps every word with its count, size, position and colour as a dataset
A few examples, all using the example data copied by net get:
1. Inaugural addresses in a heart
Code:
use cg_inaugural, clear
calligram, textvar(text) shape(heart) width(1000) height(900) maxwords(250) rotate(random) ///
savefile(heart.html) image(heart.png, replace)
Code:
use cg_inaugural, clear
calligram, textvar(text) phrases colorby(century) maxwords(200) font(Merriweather) ///
savefile(century.html) image(century.png, replace)
3. A world map: every city inside its own country, near its real location, sized by population
Code:
use cg_cities, clear
calligram, wordvar(city) countvar(population) shapes(cg_countries_shp.dta) ///
location(lat lon) near outline outlinewidth(1) outlinecolor(#b8b8b8) ///
width(2400) height(1067) maxwords(1207) minfreq(1) minfontsize(4) ///
margin(2) font(Lato) bgcolor(white) savefile(world.html) image(world.png, replace)
4. Survey weights and the results as a dataset
Code:
use cg_inaugural, clear calligram, textvar(text) phrases maxwords(100) saving(words, replace) savefile(words.html) use words, clear list rank word count fontsize in 1/10
5. Customer comments in Urdu, drawn in Nastaliq
Code:
use cg_urdu, clear
calligram [fweight = responses], textvar(text) minfreq(1) ///
stopwords(اور تھی تھا ہے لیکن مگر بہت ہوئی) ///
scriptfonts(arabic "Noto Nastaliq Urdu") shape(circle) bgcolor(#0b3d2e) ///
savefile(urdu.html) image(urdu.png, replace)
https://fahad-mirza.github.io/calligram_Stata/
The full guide and the source code are at https://github.com/fahad-mirza/calligram_Stata. calligram_gallery.do, copied by net get, builds all of the examples.
This is a beta release, so I would be grateful for any feedback, bug reports or suggestions, either here or as an issue on GitHub. When reporting a problem, the Stata version, the operating system, the output of which calligram, and the command with its output help a lot.
Best wishes,
Fahad Mirza
Examples:
The Shape of a Heart
