# How to visualise improvement over two quizzes for different groups?

For a project I have developed a teaching game, and we are evaluating its effectiveness by having the users answer a quiz before and after the game. I have two quizzes, Quiz A and Quiz B, and one set of users will answer Quiz A before the game and Quiz B after, and the other set of users will answer Quiz B first and Quiz A second, to catch anomalous results based on the questions.

I am wondering what is the best way to visualize this data to display the improvement of the users? The visualization has to have some way to differentiate between all the users' results and also identify who is in the set starting with A and the set starting with B.

Here are my results, in case they help formulate a decision:

GROUP 1
USER      PRE-GAME SCORE    POST-GAME SCORE
User 1    5                 4
User 2    1                 2
User 3    5                 5
User 4    4                 5
User 5    0                 5
User 6    0                 4

GROUP 2
USER      PRE-GAME SCORE    POST-GAME SCORE
User 7    5                 5
User 8    2                 4
User 9    4                 6
User 10   3                 2
User 11   1                 6
User 12   0                 3

• I wish I could give all the answers given as accepted answers, however I went with Tavrok's box chart for my presentation because I felt that it best displayed the correlation I was looking for. Thanks very much for all your input! – ISOmetric Mar 11 '17 at 23:06
• Correlation between which variables and how is correlation central to your problem? – Nick Cox Mar 11 '17 at 23:10

My preferred method, in basic R, would be one of the graphs as follows:

First, to set up the data (I typed this in a table in a spreadsheet then copied it to the clipboard; then I pasted it in R with the notation that follows later):

Group       Score
Grp1Pre     5
Grp1Pre     1
Grp1Pre     5
Grp1Pre     4
Grp1Pre     0
Grp1Pre     0
Grp1Post    4
Grp1Post    2
Grp1Post    5
Grp1Post    5
Grp1Post    5
Grp1Post    4
Grp2Pre     5
Grp2Pre     2
Grp2Pre     4
Grp2Pre     3
Grp2Pre     1
Grp2Pre     0
Grp2Post    5
Grp2Post    4
Grp2Post    6
Grp2Post    2
Grp2Post    6
Grp2Post    3


Graphs then created with the commands:

tests <- read.table(file = "clipboard", header = TRUE)
boxplot(tests$Score~tests$Group)
stripchart(tests$Score~tests$Group, pch = 19, method = "stack")


Resulting in:

• While I just used the default sorting for the group names, careful name choices or defining the order would put the pre before the post. – Tavrock Mar 11 '17 at 6:19

As usual in graphics, some decisions are needed on what is of most interest, what of less interest and what of no interest at all.

The grouping is stated to be important. It seems that being able to look at both individual changes and the pattern of changes, pre to post, should be important. Much of that detail is, or would be, lost in lumping each set of scores to box plots or histograms.

Other answers to date discard the user identifiers. It is easy to agree that such identifiers are the least informative part of the data; at the same time being able to look up an odd result (which person did that?) might be a detail to keep. Even if the design were anonymous, in the full project (or a similar one) there might be other data on each person.

What we don't know is the sample size of the full group. A design that works fine with a sample of 12 (presumably a preliminary sample; perhaps just a made-up sample to give the flavour) might fail to scale well to 120 (or 1200!).

A simple design, not yet shown, is just a scatter plot of post versus pre. Ties on pre and post might be resolved by jittering symbols (shaking them apart with random noise) or showing the number of ties by symbol size.

The design here focuses on showing change, sorting on pre and then post within groups. For broader discussion, see e.g.

Cox, N.J. 2009. Paired, parallel, or profile plots for changes, correlations, and other comparisons. Stata Journal 9(4): 621-639 freely accessible here

Many readers will be able to access a copy of a minor classic:

McNeil, Don. 1992. On graphing paired data. The American Statistician. 46(4): 307-311. doi: 10.1080/00031305.1992.10475915

The identifiers are kept in this design. For a (much) larger sample size, the identifiers would have to go, as they wouldn't be readable (short of an interactive design in which a mouse-over revealed identifiers on request). However, many parallel arrows should still be discernible individually with a moderate sample size. (There is an example in my paper cited earlier.)

I'd assign different arrow colours to positive and negative changes. For this small a sample, even the little use of color seems a little busy; for a larger sample it might be essential.

I used Stata; code is shown for the record.

clear
input group user pre post
1  1 5 4
1  2 1 2
1  3 5 5
1  4 4 5
1  5 0 5
1  6 0 4
2  7 5 5
2  8 2 4
2  9 4 6
2 10 3 2
2 11 1 6
2 12 0 3
end

bysort group (pre post) : gen id = _n
gen where = -1
label val group group
label def group 1 "A then B" 2 "B then A"

set scheme s1color

twoway pcarrow pre id post id, by(group, legend(off) note("")) ///
xla(none) yla(0/6, ang(h)) xtitle("") msize(medium) mc(blue)   ///
ytitle(pre and post) subtitle(,fcolor(ltblue*0.2)) aspect(1) ///
|| scatter pre id, ms(O) msize(medium)  ///
|| scatter where id, ms(none) mla(user) mlabpos(12) mlabsize(medium) ///
plotregion(margin(l+2 r+2))


Here's one way you could do it, using the ggplot2 package in R:

Then, if you want to combine the two groups (unfortunately, you can't see that two people got 5 and 5):

R code:

library(ggplot2)

d <- data.frame(Group = paste("Group", rep(1:2, each = 6*2)),
User = c(rep(1:6, 2), rep(7:12, 2)),
Stage = factor(rep(rep(c("Pre-game", "Post-game"), each=6), 2),
levels = c("Pre-game", "Post-game")),
Quiz = c(rep(c("A", "B"), each=6), rep(c("B", "A"), each=6)),
Score = c(5, 1, 5, 4, 0, 0, 4, 2, 5, 5, 5, 4,
5, 2, 4, 3, 1, 0, 5, 4, 6, 2, 6, 3))

d$StageQuiz <- factor(paste0(d$Stage, "\n(Quiz ", d\$Quiz, ")"),
levels = c("Pre-game\n(Quiz A)", "Pre-game\n(Quiz B)",
"Post-game\n(Quiz B)", "Post-game\n(Quiz A)"))

# First plot
qplot(StageQuiz, Score, data=d, geom=c("point", "line"), group=User) +
facet_grid(. ~ Group, scales="free_x") +
scale_y_continuous(breaks = 0:6) +
theme_grey(base_size = 20) +
theme(axis.title.x = element_blank(), panel.grid.minor = element_blank())

# Second plot
qplot(Stage, Score, data=d, geom=c("point", "line"), group=User) +
scale_y_continuous(breaks = 0:6) +
theme_grey(base_size = 20) +
theme(axis.title.x = element_blank(), panel.grid.minor = element_blank())