<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/visualizing-when-im-most-productive-during-the-day/"></div></div><div><a data-url="https://www.r-bloggers.com/visualizing-when-im-most-productive-during-the-day/" data-counturl="https://www.r-bloggers.com/visualizing-when-im-most-productive-during-the-day/" data-count="horizontal" data-text="Visualizing when I’m most productive during the day" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://deanattali.com/blog/visualize-git-commits-time/"> Dean Attali's R Blog</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>	Analyzing my (and others’) git activity – </p>
<p><a target="_blank" href="https://daattali.com/shiny/visualize-git-commits-time/">Click here to explore the data yourself</a></p>
<p>Yesterday I saw <a target="_blank" href="https://t.co/u3uHy6a9d4">this retweet</a> from <a target="_blank" href="https://twitter.com/timelyportfolio">@timelyportfolio</a> that links to a <a target="_blank" href="https://gist.github.com/gka/393f5ab2b95e927d305eb6e14767180e">gist by @gka</a>.</p>
<p>The gist gave a few short scripts that can show you when your git commits take place during the day. I thought that was cool, so I took it a step (or five) further by writing it all up in R code and made nice wrapper functions for it and added interactive visualizations and made a shiny app… I just had a bit of fun. This is the result.</p>
<p>Note that all commit times are reported as PST timezone.</p>
<p><strong>TL;DR: I’m dead before 10am — My prime working time is 2am — My supervisor Jenny Bryan has a very compatible schedule to mine — Hadley somehow learned in the past 3 years to be so productive that he doesn’t even work on weekends</strong></p>
<p>This post shows a few plots and discusses them, but it can be more fun to <a target="_blank" href="https://daattali.com/shiny/visualize-git-commits-time/">play with the data yourself</a>.</p>
<h2>Table of contents</h2>
<ul>
<li><a target="_blank" href="https://daattali.com/shiny/visualize-git-commits-time/">Explore the data interactively yourself</a></li>
<li><a target="_blank" href="http://deanattali.com/blog/visualize-git-commits-time/#dean-commits">My work hours since first learning R</a></li>
<li><a target="_blank" href="http://deanattali.com/blog/visualize-git-commits-time/#dean-6-months">My work hours in the past 6 months</a></li>
<li><a target="_blank" href="http://deanattali.com/blog/visualize-git-commits-time/#dean-density">Adding marginal density plots to see exactly what times are alive/dead</a></li>
<li><a target="_blank" href="http://deanattali.com/blog/visualize-git-commits-time/#jenny-commits">How’s my (ex) supervisor Jenny Bryan doing?</a></li>
<li><a target="_blank" href="http://deanattali.com/blog/visualize-git-commits-time/#hadley-commits">And the grand finale: the R master Hadley</a></li>
<li><a target="_blank" href="http://deanattali.com/blog/visualize-git-commits-time/#weekends">Working on weekends</a></li>
<li><a target="_blank" href="http://deanattali.com/blog/visualize-git-commits-time/#code">R code used to generate this data</a></li>
</ul>
<h1>My work hours since first learning R</h1>
<p>This plot shows the times of all my git commits since Sept 2013, colour-coded by git repo (aka project). The plot is fully interactive: you can zoom, move, or remove all observations from a specific repo by clicking on the repo name in the legend.</p>
<p><a target="_blank" href="https://i1.wp.com/deanattali.com/img/blog/git-commits-time/dean-commits-100.png"><img alt="Dean commits all" src="https://i1.wp.com/deanattali.com/img/blog/git-commits-time/dean-commits-100.png?w=456" data-recalc-dims="1"></a></p>
<p>September 2013 is when I first learned R in the beginning of my masters degree, and the project I was working on then (<a target="_blank" href="https://github.com/daattali/statsTerrorismProject">statsTerrorismProject</a>) was my final project for STAT545.</p>
<p>After taking my introductory R course, I spent the next year on my other masters courses and didn’t do any R-ing and coding, hence the giant gap. The next time I used git was when I took the second half of STAT545 in 2014, and that’s where I learned how to write a package – <a target="_blank" href="https://github.com/daattali/rsalad">rsalad</a> was my first R package, developed as homework. Then I didn’t do any open source work for a few months because I was working in a lab that wasn’t very supportive of that… And in January 2015 I started working with Jenny as my supervisor, and as you can see, I was pretty much busy with just about everything in the world except for my actual masters project! <img alt="🙂" class="wp-smiley" src="https://s.w.org/images/core/emoji/72x72/1f642.png"></p>
<h3>A few things that are easy to notice:</h3>
<ul>
<li>I refuse to work before 10am</li>
<li>It looks like I work until 2am-4am fairly consistently</li>
<li>I did a LOT of work on my website (<a target="_blank" href="http://daattali.github.io/">dattali.github.io</a>) around March 2015 (which is when I got the idea to make a website and when I released it)</li>
<li>There were a few days in July 2015 where I started coding at 6am! Nope, that’s a lie, I was in Toronto that week so that’s actually 9am…</li>
<li>It’s cool to see when I work on which projects. You can very clearly see the two-week effort on <a target="_blank" href="https://github.com/daattali/timevis">timevis</a> in July 2016 for example</li>
</ul>
<h1>My work hours in the past 6 months</h1>
<p><a target="_blank" href="https://i2.wp.com/deanattali.com/img/blog/git-commits-time/dean-commits-6.png"><img alt="Dean commits 6 months" src="https://i2.wp.com/deanattali.com/img/blog/git-commits-time/dean-commits-6.png?w=456" data-recalc-dims="1"></a></p>
<h3>Observations</h3>
<p>It’s interesting to see how my commits very closely relate to what’s going on in my life <img alt="🙂" class="wp-smiley" src="https://s.w.org/images/core/emoji/72x72/1f642.png"></p>
<ul>
<li>During Feb-March I was writing my masters thesis on my package <a target="_blank" href="https://github.com/daattali/ddpcr">ddpcr</a> and you can see how I had one last burst of work on the package at the end of Feb, and then I completely stopped coding for a few weeks while I focused on writing. I was such a good boy.</li>
<li>June seems like a dead month. I was in Toronto, Berkeley and Stanford for conferences and didn’t code at all. It’s cool how clearly that shows up!</li>
<li>It’s nice to see that <a target="_blank" href="https://github.com/daattali/shinyjs">shinyjs</a> has reached a fairly stable state and I don’t have to spend much time on it anymore</li>
</ul>
<h1>Adding marginal density plots to see exactly what times are alive/dead</h1>
<p>Just for fun, I can use my <a target="_blank" href="https://github.com/daattali/ggExtra">ggMarginal()</a> function to add marginal density plots, to make it more clear when most of my commits take place.</p>
<p><a target="_blank" href="https://i2.wp.com/deanattali.com/img/blog/git-commits-time/dean-density.png"><img alt="Dean density plot" src="https://i2.wp.com/deanattali.com/img/blog/git-commits-time/dean-density.png?w=456" data-recalc-dims="1"></a></p>
<h1>How’s my (ex) supervisor Jenny Bryan doing?</h1>
<p>After working with Jenny for a couple years, I learned that we have very compatible schedules. It was very normal for us to exchange emails past midnight when we had a 9am class the following morning, and I’d often see her making commits at 1-2am when I was just getting in the zone!</p>
<p>With this graph we can see that our schedules really are very similar, although she is shifted 2 hours from me: I work 10am-4am, she works 8am-2am. What an early bird.</p>
<p><a target="_blank" href="https://i0.wp.com/deanattali.com/img/blog/git-commits-time/jenny-commits-100.png"><img alt="Jenny commits all" src="https://i0.wp.com/deanattali.com/img/blog/git-commits-time/jenny-commits-100.png?w=456" data-recalc-dims="1"></a></p>
<h1>And the grand finale: the R master Hadley</h1>
<p>No introduction needed, the name speaks for itself. (Note these are all PST times)</p>
<p>Just one thing I’d like to note: we’ve all heard “this is going to be the year of ‘ggvis’!”, yet it looks like 2013 was the year-est of ‘ggvis’ so far <img alt="🙂" class="wp-smiley" src="https://s.w.org/images/core/emoji/72x72/1f642.png"></p>
<p><a target="_blank" href="https://i2.wp.com/deanattali.com/img/blog/git-commits-time/hadley-commits-100.png"><img alt="Hadley commits all" src="https://i2.wp.com/deanattali.com/img/blog/git-commits-time/hadley-commits-100.png?w=456" data-recalc-dims="1"></a></p>
<h1>Working on weekends</h1>
<p>If you look at day of the week, you’ll see that weekends and weekdays are essentially the same to me.</p>
<p><a target="_blank" href="https://i0.wp.com/deanattali.com/img/blog/git-commits-time/dean-days.png"><img alt="Dean day of week" src="https://i0.wp.com/deanattali.com/img/blog/git-commits-time/dean-days.png?w=456" data-recalc-dims="1"></a></p>
<p>But what’s amazing is that if you look at Hadley, he seems to be such a good time manager that he manages to almost never work on weekends in the past 3 years, despite producing output at a speed of a dozen adults. That discipline of not working on weekends is commendable.</p>
<p><a target="_blank" href="https://i0.wp.com/deanattali.com/img/blog/git-commits-time/hadley-days.png"><img alt="Hadley day of week" src="https://i0.wp.com/deanattali.com/img/blog/git-commits-time/hadley-days.png?w=456" data-recalc-dims="1"></a></p>
<h1>R code used to generate this data</h1>
<p>If you want to replicate these kinds of plots, here is the exact R code that was used to generate all the plots. The two functions you need to call are <code>create_git_log_file()</code> to generate the data file, and then <code>plot_git_commits()</code> to visualize the data.</p>
<p>I know this code isn’t amazing and could be optimized some more (I especially don’t love that I’m using system calls) but I wanted to get this out ASAP because I have real projects I need to work on <img alt="🙂" class="wp-smiley" src="https://s.w.org/images/core/emoji/72x72/1f642.png"></p>
<div>
<pre><code><span>#' Plot the time or date of your git commits
#' #' IMPORTANT: Before calling this function, you must use the `create_git_log_file()` function
#' to generate the data file that is used to make the plot!
#' You also need to have 'dplyr', 'git2r', 'ggplot2', 'ggExtra' and 'scales' packages installed.
#' #' @param logfile The output from `create_git_log_file()`. This is a file containing all the #' necessary info for generating the activity plots. You must call `create_git_log_file()`
#' first to create the data file, and then you can call this plot function to
#' plot the data based on that file
#' @param num_months How many months back to look at your commits
#' @param plot_type What type of plot to output (&quot;plotly&quot;, &quot;ggplot&quot;, or &quot;density&quot;)
#' if you choose &quot;density&quot; then the result will be a ggplot2 plot with marginal density plots
#' @param x The variable to plot along the x axis (one of &quot;repo&quot;, &quot;time&quot;, &quot;date&quot;, or &quot;weekday&quot;) #' @param y The variable to plot along the y axis (one of &quot;repo&quot;, &quot;time&quot;, &quot;date&quot;, or &quot;weekday&quot;) </span><span>plot_git_commits</span><span> </span><span>&lt;-</span><span> </span><span>function</span><span>(</span><span>logfile</span><span>,</span><span> </span><span>num_months</span><span> </span><span>=</span><span> </span><span>6</span><span>,</span><span>
</span><span>plot_type</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>&quot;plotly&quot;</span><span>,</span><span> </span><span>&quot;ggplot&quot;</span><span>,</span><span> </span><span>&quot;density&quot;</span><span>),</span><span>
</span><span>x</span><span> </span><span>=</span><span> </span><span>&quot;date&quot;</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>&quot;time&quot;</span><span>)</span><span> </span><span>{</span><span>
</span><span>if</span><span> </span><span>(</span><span>!</span><span>requireNamespace</span><span>(</span><span>&quot;dplyr&quot;</span><span>,</span><span> </span><span>quietly</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>))</span><span> </span><span>{</span><span>
</span><span>stop</span><span>(</span><span>&quot;You need to install the 'dplyr' package&quot;</span><span>,</span><span> </span><span>call.</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span><span>}</span><span>
</span><span>if</span><span> </span><span>(</span><span>!</span><span>requireNamespace</span><span>(</span><span>&quot;ggplot2&quot;</span><span>,</span><span> </span><span>quietly</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>))</span><span> </span><span>{</span><span>
</span><span>stop</span><span>(</span><span>&quot;You need to install the 'ggplot2' package&quot;</span><span>,</span><span> </span><span>call.</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span><span>}</span><span>
</span><span>if</span><span> </span><span>(</span><span>!</span><span>requireNamespace</span><span>(</span><span>&quot;scales&quot;</span><span>,</span><span> </span><span>quietly</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>))</span><span> </span><span>{</span><span>
</span><span>stop</span><span>(</span><span>&quot;You need to install the 'scales' package&quot;</span><span>,</span><span> </span><span>call.</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span><span>}</span><span>
</span><span>if</span><span> </span><span>(</span><span>!</span><span>requireNamespace</span><span>(</span><span>&quot;ggExtra&quot;</span><span>,</span><span> </span><span>quietly</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>))</span><span> </span><span>{</span><span>
</span><span>stop</span><span>(</span><span>&quot;You need to install the 'ggExtra' package&quot;</span><span>,</span><span> </span><span>call.</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span><span>}</span><span>
</span><span>plot_type</span><span> </span><span>&lt;-</span><span> </span><span>match.arg</span><span>(</span><span>plot_type</span><span>)</span><span>
</span><span>if</span><span> </span><span>(</span><span>!</span><span>file.exists</span><span>(</span><span>logfile</span><span>))</span><span> </span><span>{</span><span>
</span><span>stop</span><span>(</span><span>&quot;The git log file was not found&quot;</span><span>,</span><span> </span><span>call.</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span><span>}</span><span>
</span><span>if</span><span> </span><span>(</span><span>!</span><span>is.numeric</span><span>(</span><span>num_months</span><span>)</span><span> </span><span>||</span><span> </span><span>num_months</span><span> </span><span>&lt;</span><span> </span><span>1</span><span>)</span><span> </span><span>{</span><span>
</span><span>stop</span><span>(</span><span>&quot;num_months must be a positive integer&quot;</span><span>,</span><span> </span><span>call.</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span><span>}</span><span>
</span><span>if</span><span> </span><span>(</span><span>x</span><span> </span><span>==</span><span> </span><span>y</span><span> </span><span>||</span><span> </span><span>!</span><span>all</span><span>(</span><span>c</span><span>(</span><span>x</span><span>,</span><span> </span><span>y</span><span>)</span><span> </span><span>%in%</span><span> </span><span>c</span><span>(</span><span>&quot;repo&quot;</span><span>,</span><span> </span><span>&quot;time&quot;</span><span>,</span><span> </span><span>&quot;date&quot;</span><span>,</span><span> </span><span>&quot;weekday&quot;</span><span>)))</span><span> </span><span>{</span><span>
</span><span>stop</span><span>(</span><span>'x and y must each be one of &quot;repo&quot;, &quot;time&quot;, &quot;date&quot; or &quot;weekday&quot; and must be unique'</span><span>,</span><span> </span><span>call.</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span><span>}</span><span>
</span><span># read the logfile and transform it into a useful dataframe
</span><span> </span><span>gitdata</span><span> </span><span>&lt;-</span><span> </span><span>get_git_df</span><span>(</span><span>logfile</span><span>,</span><span> </span><span>num_months</span><span>)</span><span>
</span><span># plot the result
</span><span> </span><span>plot_git_commits_helper</span><span>(</span><span>gitdata</span><span>,</span><span> </span><span>plot_type</span><span>,</span><span> </span><span>x</span><span>,</span><span> </span><span>y</span><span>)</span><span>
</span><span>}</span><span>
</span><span>#' Create a data file with all the git commit info of a particular user for some repos
#' #' In order to create this data file, all the git repos specified have to be cloned to your
#' local machine (this happens automatically). The result of this function is a data file with
#' information about git commits, and this file can be used as input for `plot_git_commit_time()`
#' (which will visualize the times of day commits were made)
#' #' @param username The GitHub username of the user you want to track their commits
#' @param repos A list of all the GitHub repos you want to analyze (all these repos will get cloned locally
#' @param dir The directory where all the git repos will #' @param logfile THe name of the data file (the file with all the git lgs
</span><span>create_git_log_file</span><span> </span><span>&lt;-</span><span> </span><span>function</span><span>(</span><span>
</span><span>username</span><span> </span><span>=</span><span> </span><span>&quot;daattali&quot;</span><span>,</span><span>
</span><span>repos</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>&quot;beautiful-jekyll&quot;</span><span>,</span><span>
</span><span>&quot;shinyjs&quot;</span><span>,</span><span>
</span><span>&quot;timevis&quot;</span><span>,</span><span>
</span><span>&quot;jennybc/bingo&quot;</span><span>),</span><span>
</span><span>dir</span><span> </span><span>=</span><span>&quot;git_repos_vis&quot;</span><span>,</span><span>
</span><span>logfile</span><span> </span><span>=</span><span> </span><span>&quot;project-logs.csv&quot;</span><span>)</span><span> </span><span>{</span><span>
</span><span>if</span><span> </span><span>(</span><span>!</span><span>requireNamespace</span><span>(</span><span>&quot;git2r&quot;</span><span>,</span><span> </span><span>quietly</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>))</span><span> </span><span>{</span><span>
</span><span>stop</span><span>(</span><span>&quot;You need to install the 'git2r' package&quot;</span><span>,</span><span> </span><span>call.</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span><span>}</span><span>
</span><span>if</span><span> </span><span>(</span><span>!</span><span>dir.exists</span><span>(</span><span>dir</span><span>))</span><span> </span><span>{</span><span>
</span><span>dir.create</span><span>(</span><span>dir</span><span>,</span><span> </span><span>recursive</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>,</span><span> </span><span>showWarnings</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span><span>}</span><span>
</span><span>dir</span><span> </span><span>&lt;-</span><span> </span><span>normalizePath</span><span>(</span><span>dir</span><span>)</span><span>
</span><span># clone all the git repos into one folder
</span><span> </span><span>for</span><span> </span><span>(</span><span>repo</span><span> </span><span>in</span><span> </span><span>repos</span><span>)</span><span> </span><span>{</span><span>
</span><span>if</span><span> </span><span>(</span><span>!</span><span>grepl</span><span>(</span><span>&quot;/&quot;</span><span>,</span><span> </span><span>repo</span><span>))</span><span> </span><span>{</span><span>
</span><span>repo</span><span> </span><span>&lt;-</span><span> </span><span>paste0</span><span>(</span><span>username</span><span>,</span><span> </span><span>&quot;/&quot;</span><span>,</span><span> </span><span>repo</span><span>)</span><span>
</span><span>}</span><span>
</span><span>repo_name</span><span> </span><span>&lt;-</span><span> </span><span>sub</span><span>(</span><span>&quot;.*/(.*)&quot;</span><span>,</span><span> </span><span>replacement</span><span> </span><span>=</span><span> </span><span>&quot;\\1&quot;</span><span>,</span><span> </span><span>repo</span><span>)</span><span>
</span><span>if</span><span> </span><span>(</span><span>dir.exists</span><span>(</span><span>file.path</span><span>(</span><span>dir</span><span>,</span><span> </span><span>repo_name</span><span>)))</span><span> </span><span>{</span><span>
</span><span>message</span><span>(</span><span>&quot;Note: Not cloning &quot;</span><span>,</span><span> </span><span>repo</span><span>,</span><span> </span><span>&quot; because a folder with that name already exists&quot;</span><span>)</span><span>
</span><span>next</span><span>
</span><span>}</span><span> </span><span>else</span><span> </span><span>{</span><span>
</span><span>message</span><span>(</span><span>&quot;Cloning &quot;</span><span>,</span><span> </span><span>repo</span><span>)</span><span> </span><span>}</span><span>
</span><span>repo_url</span><span> </span><span>&lt;-</span><span> </span><span>paste0</span><span>(</span><span>&quot;https://github.com/&quot;</span><span>,</span><span> </span><span>repo</span><span>)</span><span>
</span><span>git2r</span><span>::</span><span>clone</span><span>(</span><span>url</span><span> </span><span>=</span><span> </span><span>repo_url</span><span>,</span><span> </span><span>local_path</span><span> </span><span>=</span><span> </span><span>file.path</span><span>(</span><span>dir</span><span>,</span><span> </span><span>repo_name</span><span>),</span><span> </span><span>progress</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span><span>}</span><span>
</span><span># create a shell script to get the commit logs of all repos
</span><span> </span><span>sh_script_log</span><span> </span><span>&lt;-</span><span> </span><span>paste0</span><span>(</span><span>'cd '</span><span>,</span><span> </span><span>dir</span><span>,</span><span> </span><span>' TMPLOG=$(pwd)/tmp-project-log.csv; echo &quot;project,timestamp&quot; > $TMPLOG;
for repo in *; do if [ -d $repo ] &amp;&amp; [ -d $repo/.git ]; then
cd $repo;
git log --author=&quot;'</span><span>,</span><span> </span><span>username</span><span>,</span><span> </span><span>'&quot; --pretty=format:&quot;$repo,%ai&quot; >> $TMPLOG;
echo &quot;&quot; >> $TMPLOG;
cd ..;
fi
done
grep . $TMPLOG > '</span><span>,</span><span> </span><span>logfile</span><span>,</span><span> </span><span>';
rm $TMPLOG;'</span><span>)</span><span>
</span><span>system</span><span>(</span><span>sh_script_log</span><span>)</span><span>
</span><span>logfile</span><span> </span><span>&lt;-</span><span> </span><span>file.path</span><span>(</span><span>dir</span><span>,</span><span> </span><span>logfile</span><span>)</span><span>
</span><span>if</span><span> </span><span>(</span><span>file.exists</span><span>(</span><span>logfile</span><span>))</span><span> </span><span>{</span><span>
</span><span>message</span><span>(</span><span>&quot;Created logfile at &quot;</span><span>,</span><span> </span><span>normalizePath</span><span>(</span><span>logfile</span><span>))</span><span>
</span><span>}</span><span> </span><span>else</span><span> </span><span>{</span><span>
</span><span>stop</span><span>(</span><span>&quot;The git log file could not get creatd for some reason&quot;</span><span>,</span><span> </span><span>call.</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span><span>}</span><span>
</span><span>return</span><span>(</span><span>logfile</span><span>)</span><span>
</span><span>}</span><span>
</span><span>#--- Helper functions ---#
</span><span>
</span><span>get_git_df</span><span> </span><span>&lt;-</span><span> </span><span>function</span><span>(</span><span>logfile</span><span>,</span><span> </span><span>num_months</span><span>)</span><span> </span><span>{</span><span>
</span><span>library</span><span>(</span><span>dplyr</span><span>)</span><span>
</span><span>date_cutoff</span><span> </span><span>&lt;-</span><span> </span><span>as.POSIXct</span><span>(</span><span>seq</span><span>(</span><span>Sys.Date</span><span>(),</span><span> </span><span>length</span><span> </span><span>=</span><span> </span><span>2</span><span>,</span><span> </span><span>by</span><span> </span><span>=</span><span> </span><span>paste0</span><span>(</span><span>-</span><span>num_months</span><span>,</span><span> </span><span>&quot; months&quot;</span><span>))[</span><span>2</span><span>])</span><span>
</span><span>gitdata</span><span> </span><span>&lt;-</span><span> </span><span>read.csv</span><span>(</span><span>logfile</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>dplyr</span><span>::</span><span>filter</span><span>(</span><span>project</span><span> </span><span>!=</span><span> </span><span>&quot;&quot;</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>dplyr</span><span>::</span><span>mutate</span><span>(</span><span>ts</span><span> </span><span>=</span><span> </span><span>as.POSIXct</span><span>(</span><span>timestamp</span><span>))</span><span> </span><span>%>%</span><span>
</span><span>dplyr</span><span>::</span><span>filter</span><span>(</span><span>ts</span><span> </span><span>>=</span><span> </span><span>date_cutoff</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>dplyr</span><span>::</span><span>mutate</span><span>(</span><span>
</span><span>repo</span><span> </span><span>=</span><span> </span><span>as.factor</span><span>(</span><span>project</span><span>),</span><span>
</span><span>date</span><span> </span><span>=</span><span> </span><span>as.Date</span><span>(</span><span>ts</span><span>),</span><span>
</span><span>time_short</span><span> </span><span>=</span><span> </span><span>strftime</span><span>(</span><span>ts</span><span>,</span><span> </span><span>format</span><span> </span><span>=</span><span> </span><span>&quot;%H:%M&quot;</span><span>),</span><span>
</span><span>time</span><span> </span><span>=</span><span> </span><span>as.POSIXct</span><span>(</span><span>time_short</span><span>,</span><span> </span><span>format</span><span> </span><span>=</span><span> </span><span>&quot;%H:%M&quot;</span><span>,</span><span> </span><span>tz</span><span> </span><span>=</span><span> </span><span>&quot;PST&quot;</span><span>),</span><span>
</span><span>weekday</span><span> </span><span>=</span><span> </span><span>factor</span><span>(</span><span>weekdays</span><span>(</span><span>date</span><span>),</span><span>
</span><span>levels</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>&quot;Monday&quot;</span><span>,</span><span> </span><span>&quot;Tuesday&quot;</span><span>,</span><span> </span><span>&quot;Wednesday&quot;</span><span>,</span><span>
</span><span>&quot;Thursday&quot;</span><span>,</span><span> </span><span>&quot;Friday&quot;</span><span>,</span><span> </span><span>&quot;Saturday&quot;</span><span>,</span><span> </span><span>&quot;Sunday&quot;</span><span>))</span><span>
</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>dplyr</span><span>::</span><span>select</span><span>(</span><span>repo</span><span>,</span><span> </span><span>date</span><span>,</span><span> </span><span>time_short</span><span>,</span><span> </span><span>time</span><span>,</span><span> </span><span>weekday</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>droplevels</span><span>()</span><span>
</span><span>gitdata</span><span>
</span><span>}</span><span>
</span><span>plot_git_commits_helper</span><span> </span><span>&lt;-</span><span> </span><span>function</span><span>(</span><span>gitdata</span><span>,</span><span> </span><span>plot_type</span><span> </span><span>=</span><span> </span><span>&quot;plotly&quot;</span><span>,</span><span> </span><span>x</span><span> </span><span>=</span><span> </span><span>&quot;repo&quot;</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>&quot;time&quot;</span><span>)</span><span> </span><span>{</span><span>
</span><span># Define a large set of distinct colours
</span><span> </span><span>all_cols</span><span> </span><span>&lt;-</span><span> </span><span>c</span><span>(</span><span>
</span><span>&quot;#FFFF00&quot;</span><span>,</span><span> </span><span>&quot;#1CE6FF&quot;</span><span>,</span><span> </span><span>&quot;#FF34FF&quot;</span><span>,</span><span> </span><span>&quot;#FF4A46&quot;</span><span>,</span><span> </span><span>&quot;#008941&quot;</span><span>,</span><span> </span><span>&quot;#006FA6&quot;</span><span>,</span><span> </span><span>&quot;#A30059&quot;</span><span>,</span><span> </span><span>&quot;#000000&quot;</span><span>,</span><span> </span><span>&quot;#FFDBE5&quot;</span><span>,</span><span> </span><span>&quot;#7A4900&quot;</span><span>,</span><span> </span><span>&quot;#0000A6&quot;</span><span>,</span><span> </span><span>&quot;#B79762&quot;</span><span>,</span><span> </span><span>&quot;#004D43&quot;</span><span>,</span><span> </span><span>&quot;#8FB0FF&quot;</span><span>,</span><span> </span><span>&quot;#63FFAC&quot;</span><span>,</span><span> </span><span>&quot;#997D87&quot;</span><span>,</span><span>
</span><span>&quot;#5A0007&quot;</span><span>,</span><span> </span><span>&quot;#809693&quot;</span><span>,</span><span> </span><span>&quot;#FEFFE6&quot;</span><span>,</span><span> </span><span>&quot;#1B4400&quot;</span><span>,</span><span> </span><span>&quot;#4FC601&quot;</span><span>,</span><span> </span><span>&quot;#3B5DFF&quot;</span><span>,</span><span> </span><span>&quot;#4A3B53&quot;</span><span>,</span><span> </span><span>&quot;#FF2F80&quot;</span><span>,</span><span>
</span><span>&quot;#61615A&quot;</span><span>,</span><span> </span><span>&quot;#BA0900&quot;</span><span>,</span><span> </span><span>&quot;#6B7900&quot;</span><span>,</span><span> </span><span>&quot;#00C2A0&quot;</span><span>,</span><span> </span><span>&quot;#FFAA92&quot;</span><span>,</span><span> </span><span>&quot;#FF90C9&quot;</span><span>,</span><span> </span><span>&quot;#B903AA&quot;</span><span>,</span><span> </span><span>&quot;#D16100&quot;</span><span>,</span><span>
</span><span>&quot;#DDEFFF&quot;</span><span>,</span><span> </span><span>&quot;#000035&quot;</span><span>,</span><span> </span><span>&quot;#7B4F4B&quot;</span><span>,</span><span> </span><span>&quot;#A1C299&quot;</span><span>,</span><span> </span><span>&quot;#300018&quot;</span><span>,</span><span> </span><span>&quot;#0AA6D8&quot;</span><span>,</span><span> </span><span>&quot;#013349&quot;</span><span>,</span><span> </span><span>&quot;#00846F&quot;</span><span>,</span><span>
</span><span>&quot;#372101&quot;</span><span>,</span><span> </span><span>&quot;#FFB500&quot;</span><span>,</span><span> </span><span>&quot;#C2FFED&quot;</span><span>,</span><span> </span><span>&quot;#A079BF&quot;</span><span>,</span><span> </span><span>&quot;#CC0744&quot;</span><span>,</span><span> </span><span>&quot;#C0B9B2&quot;</span><span>,</span><span> </span><span>&quot;#C2FF99&quot;</span><span>,</span><span> </span><span>&quot;#001E09&quot;</span><span>,</span><span>
</span><span>&quot;#00489C&quot;</span><span>,</span><span> </span><span>&quot;#6F0062&quot;</span><span>,</span><span> </span><span>&quot;#0CBD66&quot;</span><span>,</span><span> </span><span>&quot;#EEC3FF&quot;</span><span>,</span><span> </span><span>&quot;#456D75&quot;</span><span>,</span><span> </span><span>&quot;#B77B68&quot;</span><span>,</span><span> </span><span>&quot;#7A87A1&quot;</span><span>,</span><span> </span><span>&quot;#788D66&quot;</span><span>,</span><span>
</span><span>&quot;#885578&quot;</span><span>,</span><span> </span><span>&quot;#FAD09F&quot;</span><span>,</span><span> </span><span>&quot;#FF8A9A&quot;</span><span>,</span><span> </span><span>&quot;#D157A0&quot;</span><span>,</span><span> </span><span>&quot;#BEC459&quot;</span><span>,</span><span> </span><span>&quot;#456648&quot;</span><span>,</span><span> </span><span>&quot;#0086ED&quot;</span><span>,</span><span> </span><span>&quot;#886F4C&quot;</span><span>,</span><span>
</span><span>&quot;#34362D&quot;</span><span>,</span><span> </span><span>&quot;#B4A8BD&quot;</span><span>,</span><span> </span><span>&quot;#00A6AA&quot;</span><span>,</span><span> </span><span>&quot;#452C2C&quot;</span><span>,</span><span> </span><span>&quot;#636375&quot;</span><span>,</span><span> </span><span>&quot;#A3C8C9&quot;</span><span>,</span><span> </span><span>&quot;#FF913F&quot;</span><span>,</span><span> </span><span>&quot;#938A81&quot;</span><span>,</span><span>
</span><span>&quot;#575329&quot;</span><span>,</span><span> </span><span>&quot;#00FECF&quot;</span><span>,</span><span> </span><span>&quot;#B05B6F&quot;</span><span>,</span><span> </span><span>&quot;#8CD0FF&quot;</span><span>,</span><span> </span><span>&quot;#3B9700&quot;</span><span>,</span><span> </span><span>&quot;#04F757&quot;</span><span>,</span><span> </span><span>&quot;#C8A1A1&quot;</span><span>,</span><span> </span><span>&quot;#1E6E00&quot;</span><span>,</span><span>
</span><span>&quot;#7900D7&quot;</span><span>,</span><span> </span><span>&quot;#A77500&quot;</span><span>,</span><span> </span><span>&quot;#6367A9&quot;</span><span>,</span><span> </span><span>&quot;#A05837&quot;</span><span>,</span><span> </span><span>&quot;#6B002C&quot;</span><span>,</span><span> </span><span>&quot;#772600&quot;</span><span>,</span><span> </span><span>&quot;#D790FF&quot;</span><span>,</span><span> </span><span>&quot;#9B9700&quot;</span><span>,</span><span>
</span><span>&quot;#549E79&quot;</span><span>,</span><span> </span><span>&quot;#FFF69F&quot;</span><span>,</span><span> </span><span>&quot;#201625&quot;</span><span>,</span><span> </span><span>&quot;#72418F&quot;</span><span>,</span><span> </span><span>&quot;#BC23FF&quot;</span><span>,</span><span> </span><span>&quot;#99ADC0&quot;</span><span>,</span><span> </span><span>&quot;#3A2465&quot;</span><span>,</span><span> </span><span>&quot;#922329&quot;</span><span>,</span><span>
</span><span>&quot;#5B4534&quot;</span><span>,</span><span> </span><span>&quot;#FDE8DC&quot;</span><span>,</span><span> </span><span>&quot;#404E55&quot;</span><span>,</span><span> </span><span>&quot;#0089A3&quot;</span><span>,</span><span> </span><span>&quot;#CB7E98&quot;</span><span>,</span><span> </span><span>&quot;#A4E804&quot;</span><span>,</span><span> </span><span>&quot;#324E72&quot;</span><span>,</span><span> </span><span>&quot;#6A3A4C&quot;</span><span>)</span><span>
</span><span>library</span><span>(</span><span>ggplot2</span><span>)</span><span>
</span><span>p</span><span> </span><span>&lt;-</span><span> </span><span>ggplot</span><span>(</span><span>gitdata</span><span>,</span><span> </span><span>aes_string</span><span>(</span><span>x</span><span>,</span><span> </span><span>y</span><span>,</span><span> </span><span>label</span><span> </span><span>=</span><span> </span><span>&quot;time_short&quot;</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_point</span><span>(</span><span>aes</span><span>(</span><span>fill</span><span> </span><span>=</span><span> </span><span>repo</span><span>),</span><span> </span><span>col</span><span> </span><span>=</span><span> </span><span>&quot;#555555&quot;</span><span>,</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>5</span><span>,</span><span>
</span><span>shape</span><span> </span><span>=</span><span> </span><span>21</span><span>,</span><span> </span><span>position</span><span> </span><span>=</span><span> </span><span>position_jitter</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme_bw</span><span>(</span><span>20</span><span>)</span><span> </span><span>+</span><span> </span><span>xlab</span><span>(</span><span>NULL</span><span>)</span><span> </span><span>+</span><span> </span><span>ylab</span><span>(</span><span>NULL</span><span>)</span><span> </span><span>+</span><span>
</span><span>scale_fill_manual</span><span>(</span><span>values</span><span> </span><span>=</span><span> </span><span>all_cols</span><span>[</span><span>seq_along</span><span>(</span><span>unique</span><span>(</span><span>gitdata</span><span>$</span><span>repo</span><span>))])</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>legend.position</span><span> </span><span>=</span><span> </span><span>&quot;bottom&quot;</span><span>)</span><span>
</span><span>if</span><span> </span><span>(</span><span>x</span><span> </span><span>==</span><span> </span><span>&quot;date&quot;</span><span>)</span><span> </span><span>{</span><span>
</span><span>p</span><span> </span><span>&lt;-</span><span> </span><span>p</span><span> </span><span>+</span><span>
</span><span>scale_x_date</span><span>()</span><span>
</span><span>}</span><span> </span><span>else</span><span> </span><span>if</span><span> </span><span>(</span><span>x</span><span> </span><span>==</span><span> </span><span>&quot;time&quot;</span><span>)</span><span> </span><span>{</span><span>
</span><span>p</span><span> </span><span>&lt;-</span><span> </span><span>p</span><span> </span><span>+</span><span>
</span><span>scale_x_datetime</span><span>(</span><span>labels</span><span> </span><span>=</span><span> </span><span>scales</span><span>::</span><span>date_format</span><span>(</span><span>&quot;%H:00&quot;</span><span>),</span><span> </span><span>date_breaks</span><span> </span><span>=</span><span> </span><span>&quot;2 hour&quot;</span><span>)</span><span>
</span><span>}</span><span> </span><span>else</span><span> </span><span>{</span><span>
</span><span>p</span><span> </span><span>&lt;-</span><span> </span><span>p</span><span> </span><span>+</span><span> </span><span>ggExtra</span><span>::</span><span>rotateTextX</span><span>()</span><span>
</span><span>}</span><span>
</span><span>if</span><span> </span><span>(</span><span>y</span><span> </span><span>==</span><span> </span><span>&quot;date&quot;</span><span>)</span><span> </span><span>{</span><span>
</span><span>p</span><span> </span><span>&lt;-</span><span> </span><span>p</span><span> </span><span>+</span><span>
</span><span>scale_y_date</span><span>()</span><span>
</span><span>}</span><span> </span><span>else</span><span> </span><span>if</span><span> </span><span>(</span><span>y</span><span> </span><span>==</span><span> </span><span>&quot;time&quot;</span><span>)</span><span> </span><span>{</span><span>
</span><span>p</span><span> </span><span>&lt;-</span><span> </span><span>p</span><span> </span><span>+</span><span>
</span><span>scale_y_datetime</span><span>(</span><span>labels</span><span> </span><span>=</span><span> </span><span>scales</span><span>::</span><span>date_format</span><span>(</span><span>&quot;%H:00&quot;</span><span>),</span><span> </span><span>date_breaks</span><span> </span><span>=</span><span> </span><span>&quot;2 hour&quot;</span><span>)</span><span>
</span><span>}</span><span>
</span><span>if</span><span> </span><span>(</span><span>plot_type</span><span> </span><span>==</span><span> </span><span>&quot;plotly&quot;</span><span>)</span><span> </span><span>{</span><span>
</span><span>if</span><span> </span><span>(</span><span>!</span><span>requireNamespace</span><span>(</span><span>&quot;plotly&quot;</span><span>,</span><span> </span><span>quietly</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>))</span><span> </span><span>{</span><span>
</span><span>stop</span><span>(</span><span>&quot;You need to install the 'plotly' package&quot;</span><span>,</span><span> </span><span>call.</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span><span>}</span><span>
</span><span>if</span><span> </span><span>(</span><span>x</span><span> </span><span>==</span><span> </span><span>&quot;time&quot;</span><span>)</span><span> </span><span>{</span><span>
</span><span>tooltip</span><span> </span><span>&lt;-</span><span> </span><span>c</span><span>(</span><span>&quot;fill&quot;</span><span>,</span><span> </span><span>&quot;label&quot;</span><span>,</span><span> </span><span>&quot;y&quot;</span><span>)</span><span>
</span><span>}</span><span> </span><span>else</span><span> </span><span>if</span><span> </span><span>(</span><span>y</span><span> </span><span>==</span><span> </span><span>&quot;time&quot;</span><span>)</span><span> </span><span>{</span><span>
</span><span>tooltip</span><span> </span><span>&lt;-</span><span> </span><span>c</span><span>(</span><span>&quot;fill&quot;</span><span>,</span><span> </span><span>&quot;x&quot;</span><span>,</span><span> </span><span>&quot;label&quot;</span><span>)</span><span>
</span><span>}</span><span> </span><span>else</span><span> </span><span>{</span><span>
</span><span>tooltip</span><span> </span><span>&lt;-</span><span> </span><span>c</span><span>(</span><span>&quot;fill&quot;</span><span>,</span><span> </span><span>&quot;x&quot;</span><span>,</span><span> </span><span>&quot;y&quot;</span><span>)</span><span>
</span><span>}</span><span>
</span><span>p</span><span> </span><span>&lt;-</span><span> </span><span>plotly</span><span>::</span><span>ggplotly</span><span>(</span><span>p</span><span>,</span><span> </span><span>tooltip</span><span> </span><span>=</span><span> </span><span>tooltip</span><span>)</span><span>
</span><span>}</span><span> </span><span>else</span><span> </span><span>if</span><span> </span><span>(</span><span>plot_type</span><span> </span><span>==</span><span> </span><span>&quot;density&quot;</span><span>)</span><span> </span><span>{</span><span>
</span><span>p</span><span> </span><span>&lt;-</span><span> </span><span>ggExtra</span><span>::</span><span>ggMarginal</span><span>(</span><span>p</span><span>)</span><span>
</span><span>}</span><span>
</span><span>p</span><span>
</span><span>}</span><span>
</span></code></pre>
</div>
<p><div><div><div><div data-width="55" data-show-faces="false" data-send="true" data-layout="box_count" data-height="62" data-href="https://www.r-bloggers.com/visualizing-when-im-most-productive-during-the-day/"></div></div><div><a data-url="https://www.r-bloggers.com/visualizing-when-im-most-productive-during-the-day/" data-counturl="https://www.r-bloggers.com/visualizing-when-im-most-productive-during-the-day/" data-count="vertical" data-text="Visualizing when I’m most productive during the day" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://deanattali.com/blog/visualize-git-commits-time/"> Dean Attali's R Blog</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/?s=data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/?s=Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/?s=map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/?s=animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/?s=sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/?s=LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/?s=SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/?s=git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/?s=hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/?s=Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/?s=PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/?s=time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/?s=trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/KHLe37IjVTE"></a></div>