Create a gist now

Instantly share code, notes, and snippets.

@ChrisK91 /create.R Secret
Created Feb 3, 2018

What would you like to do?
Code to create graphics for Anki -> R article on http://chrisk91.me
require(RSQLite)
require(DBI)
require(ggplot2)
require(jsonlite)
require(ggthemes)
save_plot <- function(plot, filename, widthpx = 800, heightpx = 500){
dpi <- 120
width <- widthpx / dpi
height <- heightpx / dpi
ggsave(filename, plot, width = width, height = height, units = "in", dpi = dpi)
}
connection <- dbConnect(SQLite(), dbname="collection.anki2")
result <- dbSendQuery(connection, "SELECT * from cards")
cardData <- dbFetch(result)
dbClearResult(result)
result <- dbSendQuery(connection, "SELECT * from col")
collectionData <- dbFetch(result)
dbClearResult(result)
result <- dbSendQuery(connection, "SELECT * from notes")
notesData <- dbFetch(result)
dbClearResult(result)
result <- dbSendQuery(connection, "SELECT * from revlog")
revisionData <- dbFetch(result)
dbClearResult(result)
dbDisconnect(connection)
collectionNames <- fromJSON(txt=collectionData$decks[1])
getDeckName <- function(x) collectionNames[[x]]$name
cardData$deck <- factor(mapply(getDeckName, as.character(cardData$did))) #perform lookup of deck names
getDeckNameFromCid <- function(x){
lookup <- as.character(cardData$deck[cardData$id == x])
if(identical(lookup, character(0))) #due to deleted cards, some lookups might fail
{
lookup <- "Removed card"
}
return(lookup)
}
revisionData$deck <- factor(mapply(getDeckNameFromCid, revisionData$cid))
tmp <- ggplot(revisionData, aes(time / 1000)) + geom_histogram(binwidth = 10) + xlab("time spent reviewing a single card\n(seconds)") + scale_y_log10() + ggtitle("Review times")
save_plot(tmp + theme_minimal(), "histogram.png")
tmp <- ggplot(revisionData, aes(time / 1000, fill = deck)) + guides(fill=FALSE) + geom_histogram(binwidth = 10) + xlim(0, 400) + xlab("time spent reviewing a single card\n(seconds)") + scale_y_log10() + ggtitle("Review times") + facet_wrap(~ deck)
save_plot(tmp + theme_minimal() + ggthemes::scale_fill_gdocs(), "histogram_decks.png", widthpx = 800, heightpx = 800)
tmp <- ggplot(cardData, aes(ivl, fill = deck)) + guides(fill=FALSE) + geom_histogram(binwidth = 10) + facet_wrap(~ deck, scales = "free_y") + xlab("interval")
save_plot(tmp + theme_minimal() + ggthemes::scale_fill_gdocs(), "histogram_review_times.png", widthpx = 800, heightpx = 800)
plotWidth <- floor(sqrt(nrow(cardData))) # our final dimesnion should be a square
cardData$index <- (0 : (nrow(cardData) - 1)) # to calculate the position of each card, we need a running count
cardData$X <- cardData$index %% plotWidth # x position
cardData$Y <- cardData$index %/% plotWidth # y position
cardData$mature <- cardData$ivl > 21 # you can also use this, to show mature cards
tmp <- ggplot(cardData, aes(X, Y)) + geom_tile(aes(fill = ivl)) + scale_fill_gradient2(mid = "#dd6a27", high = "#12e824")
save_plot(tmp + theme_void() + guides(fill = FALSE), "review_heatmap.png", widthpx = 400, heightpx = 400)
# Lets filter out premade decks
cardDataFiltered <- cardData[!(cardData$deck %in% c("Sprachen::Französisch::5000 Most Common French Words", "Sprachen::Französisch::Verben mit Konjugationen")), ]
plotWidth <- floor(sqrt(nrow(cardDataFiltered))) # our final dimesnion should be a square
cardDataFiltered$index <- (0 : (nrow(cardDataFiltered) - 1)) # to calculate the position of each card, we need a running count
cardDataFiltered$X <- cardDataFiltered$index %% plotWidth # x position
cardDataFiltered$Y <- cardDataFiltered$index %/% plotWidth # y position
cardDataFiltered$mature <- cardDataFiltered$ivl > 21 # you can also use this, to show mature cards
tmp <- ggplot(cardDataFiltered, aes(X, Y)) + geom_tile(aes(fill = mature))
save_plot(tmp + theme_void() + guides(fill = FALSE), "review_heatmap_filtered.png", widthpx = 400, heightpx = 400)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment