asjadnaqvi / stata-joyplot

A Stata package for creating joyplots or ridgeline plots.
MIT License
34 stars 3 forks source link
graph joyplot ridgeline stata

StataMin issues license Stars version release

Installation | Syntax | Examples | Feedback | Change log


joyplot-1

joyplot v1.71

(03 Oct 2023)

This package provides the ability to draw joyplot or ridgeline plots in Stata. It is based on the Joyplot Guide that I released in October 2020.

Installation

The package can be installed via SSC or GitHub. The GitHub version, might be more recent due to bug fixes, feature updates etc, and may contain syntax improvements and changes in default values. See version numbers below. Eventually the GitHub version is published on SSC.

The package (v1.71) is available on SSC and can be installed as follows:

ssc install joyplot, replace

Or it can be installed from GitHub (v1.71):

net install joyplot, from("https://raw.githubusercontent.com/asjadnaqvi/stata-joyplot/main/installation/") replace

The palettes package is required to run this command:

ssc install palettes, replace
ssc install colrspace, replace

Even if you have the package installed, make sure that it is updated ado update, update.

If you want to make a clean figure, then it is advisable to load a clean scheme. These are several available and I personally use the following:

ssc install schemepack, replace
set scheme white_tableau  

You can also push the scheme directly into the graph using the scheme(schemename) option. See the help file for details or the example below.

I also prefer narrow fonts in figures with long labels. You can change this as follows:

graph set window fontface "Arial Narrow"

Syntax

The syntax for the latest version is as follows:

joyplot y [x] [if] [in], by(variable) 
                [ overlap(num) bwidth(num) palette(str) alpha(num) offset(num) lines droplow normalize(local|global) 
                   rescale offset(num) laboffset(num) lwidth(num) lcolor(str) ylabsize(num) ylabcolor(str) ylabposition(str)
                   yline ylcolor(str) ylwidth(str) ylpattern(str) xreverse yreverse peaks peaksize(num) n(num)
                   xtitle(str) ytitle(str) title(str) subtitle(str) xlabel(str)note(str) scheme(str) name(str) saving(str) 
                ]

See the help file help joyplot for details.

The most basic use is as follows:

joyplot y x, by(variable)

or

joyplot y, by(variable)

where y is the variable we want to plot, and x is usually the time dimension. The over variable splits the data into different groupings that also determines the colors. The color schemes can be modified using the color() option. Here any scheme from the colorpalettes package can be used.

Examples

Set up the data:

clear
set scheme white_tableau
graph set window fontface "Arial Narrow"

use "https://github.com/asjadnaqvi/stata-joyplot/blob/main/data/OWID_data2.dta?raw=true", clear

Two variables

We can generate basic graphs as follows:

joyplot new_cases date if date > 22460, by(country) 
joyplot new_cases date if date > 22460, by(country) norm(local)
joyplot new_cases date if date > 22460, by(country) yline bwid(0.1) norm(local)
joyplot new_cases date if date > 22460, by(country) alpha(100) bwid(0.1) norm(local)
joyplot new_cases date if date > 22460, by(country) lc(black) palette(white) alpha(100) bwid(0.1) norm(local)
joyplot new_cases date if date > 22460, by(country) lc(white) palette(black) alpha(50) lw(0.05) bwid(0.1) norm(local)
joyplot new_cases date if date > 22460, by(country) lines lw(0.2) bwid(0.1) norm(local)
joyplot new_cases date if date > 22460, by(country) lines lw(0.2) palette(black) bwid(0.1) norm(local)
joyplot new_cases date if date > 22460, by(country) lines lw(0.2) bwid(0.1) ylabpos(right) norm(local) offset(8)
joyplot new_cases date if date > 22460, by(country) lw(0.2) bwid(0.1) ylabpos(right) xsize(5) ysize(5) norm(local) offset(10)
joyplot new_cases date if date > 22460, by(country) bwid(0.1) yrev norm(local)

Here we reverse both axes, but it is highly advisable not to do so with the x-axis:

joyplot new_cases date if date > 22460, by(country) bwid(0.1) yrev xrev norm(local) yline laboff(-20) 

Normalization

joyplot new_cases date if date > 22460, by(country) bwid(0.1) norm(local)
joyplot new_cases date if date > 22460, by(country) bwid(0.1) overlap(15) norm(local)
joyplot new_cases date if date > 22460, by(country) bwid(0.1) overlap(12) lines norm(local)
joyplot new_cases date if date > 22460, by(country) bwid(0.1) off(-20) overlap(10) lw(none)  norm(local)

We can also customize dates, increase the overlap of the layers, change the palette, and change the color intensity:

qui summ date if date > 22460

local xmin = r(min)
local xmax = r(max)

joyplot new_cases date if date > 22460, by(country) overlap(8) bwid(0.1) palette(CET C1) alpha(100) ///
    lc(white) lw(0.2) xlabel(`xmin'(120)`xmax') off(-30) norm(local) ///
    xtitle("Date") ytitle("Countries") ///
    title("{fontface Arial Bold:My joyplot/ridgeline plot}") subtitle("Some more text here")  ///
    note("Some text here", size(vsmall))  

Next we modify the scheme and make sure the colors are passed correctly. We use neon from schemepack which has a black background:

qui summ date if date > 22460

local xmin = r(min)
local xmax = r(max)

joyplot new_cases date if date > 22460, by(country) overlap(8) bwid(0.1) palette(CET C1) alpha(90) ///
    lc(black) lw(0.1) xlabel(`xmin'(120)`xmax') off(-30)  norm(local) ///
    ylabc(white) /// 
    xtitle("Date") ytitle("Countries") ///
    title("{fontface Arial Bold:My joyplot}") subtitle("a subtitle here", color(white)) ///
    note("Some text here", size(vsmall)) scheme(neon)

The Joy Division look, since this plots get their name from the band:

qui summ date if date > 22425

local xmin = r(min)
local xmax = r(max)

joyplot new_cases date if date > 22425, by(country) overlap(10) bwid(0.1) palette(black) alpha(100) norm(local)  ///
    lc(white) lw(0.2) xlabel(none) laboff(40) ///
    ylabc(none)   /// 
    xtitle("") ytitle("") ///
    title("{fontface Arial Bold:The Joy Division look}") scheme(neon)

v1.7 options

In v1.7, joyplot can be replaced with ridgeline, peaks can be added to the ridges, and xline() has been enabled:

ridgeline new_cases date if date > 22460, by(country) bwid(0.1) off(-20) overlap(8) peaks norm(local) xline(22700 23000)

Single variable

Load the data that contains average USA state-level monthly temperatures for the period 1991-2020:

use "https://github.com/asjadnaqvi/stata-joyplot/blob/main/data/us_meantemp.dta?raw=true", clear

lab de month 1 "Jan" 2 "Feb" 3 "Mar" 4 "Apr" 5 "May" 6 "Jun" 7 "Jul" 8 "Aug" 9 "Sep" 10 "Oct" 11 "Nov" 12 "Dec", replace
lab val month month
joyplot meantemp, by(month)  
joyplot meantemp, by(month) yline bwid(1.2)
joyplot meantemp, by(month) yline yrev  bwid(1.2)
joyplot meantemp, by(month) yline ylw(0.2) ylc(blue) ylp(dot) ylabpos(right) bwid(1.2)
joyplot meantemp, by(month) bwid(1.5) ylabs(3) overlap(3) yline yrev palette(CET C6) ///
    xlabel(-20(10)30) ///
    ytitle("Month") xtitle("degrees Centigrade") ///
    title("Mean average temperature in the USA") subtitle("2009-2020 average") ///
    note("Source: World Bank Climate Change Knowledge Portal (CCKP).", size(vsmall)) ///
        xsize(4) ysize(5)
qui summ meantemp 

local xmin = r(min)
local xmax = r(max)

joyplot meantemp, by(month) bwid(1.5) ylabs(3) overlap(3) yline palette(scico corkO) alpha(100) ///
    ytitle("Month") xtitle("degrees Centigrade") xlabel(`xmin'(5)`xmax') ///
    title("Mean average temperature in the USA") subtitle("2009-2020 average") ///
    note("Source: World Bank Climate Change Knowledge Portal (CCKP).", size(vsmall)) ///
        xsize(3) ysize(5)

v1.7 options

ridgeline meantemp, by(month) bwid(1.5) ylabs(3) overlap(3) lc(black) yline yrev palette(CET C6) ///
    xlabel(-20(10)30) ///
    ytitle("Month") xtitle("degrees Centigrade") ///
    title("Mean average temperature in the USA") subtitle("2009-2020 average") ///
    note("Source: World Bank Climate Change Knowledge Portal (CCKP).", size(vsmall)) ///
        xsize(4) ysize(5) xline(-10 0 10) peak peaksize(0.4) // saving(test1)

Rescale and error checks (v1.6)

Load a dummy data set

use "https://github.com/asjadnaqvi/stata-joyplot/blob/main/data/rescale_test.dta?raw=true", clear
use rescale_test, clear
drop if inlist(country, "Cambodia", "Myanmar", "Lao PDR")
tab country

Do a vanilla joyplot:

joyplot socMob year, by(country)  ///
    lc(white) lw(0.2) xlabel(1990(5)2020) 

Get rid of the overlaps. Here overlap(1) gives each country it's own box:

joyplot socMob year, by(country) overlap(1) rescale  ///
    lc(white) lw(0.2) xlabel(1990(5)2020) 

Let's make a country unusable:

drop if year < 2015 & country=="Vietnam"    

joyplot socMob year, by(country) overlap(1)     ///
    lc(white) lw(0.2)  off(-2) xlabel(1990(5)2020) 

The above code will produce an error message, highlighting where the errors exist. Let's throw these out using the droplow option:

joyplot socMob year, by(country) overlap(1) droplow   ///
    lc(white) lw(0.2)  off(-2) xlabel(1990(5)2020) 

And we rescale the data further to the minimum and maximum values:

joyplot socMob year, by(country) overlap(1) droplow rescale   ///
    lc(white) lw(0.2)  off(-2) xlabel(1990(5)2020) 

Feedback

Please open an issue to report errors, feature enhancements, and/or other requests.

Change log

v1.71 (03 Oct 2023)

v1.7 (14 Jul 2023)

v1.62 (28 May 2023)

v1.61 (01 Mar 2023)

v1.6 (05 Nov 2022)

v1.5 (03 Sep 2022)

v1.42 (22 Jun 2022)

v1.41 (20 Jun 2022)

v1.4 (26 Apr 2022)

v1.3 (24 Apr 2022)

v1.21 (15 Apr 2022)

v1.2 (14 Apr 2022)

v1.1 (08 Apr 2022)

v1.0 (13 Dec 2021)