Home > Software engineering >  Flatten broken horizontal bar chart to line graph or heatmap
Flatten broken horizontal bar chart to line graph or heatmap

Time:11-19

I have data for all the time I've spent coding. This data is represented as a dictionary where the key is the date and the value is a list of tuples containing the time I started a coding session and how long the coding session lasted.

I have successfully plotted this on a enter image description here

CodePudding user response:

One way to do it is to use sampling. Choose how many samples you want to take in a given interval (the precision, for example 288 samples per day) and split each interval by that number of samples and count how many sessions are within this sample. The downside to this is that it can't be 100% precise and increasing the precision increases the time it takes to generate (for me, it takes several minutes to generate a second-precise image, though this level of precision makes little to no difference to the result).

Here is some code which can produce both a heatmap and a line graph

# Configuration options
precisionPerDay = 288
timeTicksPerDay = 24
timeTickRotation = 60
timeTickFontSize = 6
heatmap = True

# Constants
hoursInDay = 24
secondsInHour = 3600
secondsInDay = hoursInDay*secondsInHour
xInterval = secondsInDay/precisionPerDay
timeTickSecondInterval = precisionPerDay/timeTicksPerDay
timeTickHourInterval = hoursInDay/timeTicksPerDay

# Calculating x-axis (time) ticks
xAxis = range(precisionPerDay)
timeTickLabels = []
timeTickLocations = []
for timeTick in range(timeTicksPerDay):
    timeTickLocations.append(int(timeTick*timeTickSecondInterval))
    hours = timeTick/timeTicksPerDay*hoursInDay
    hour = int(hours)
    minute = int((hours-hour)*60)
    timeTickLabels.append(f"{hour:02d}:{minute:02d}")

# Calculating y-axis (height)
heights = []
for dayX in xAxis:
    rangeStart = dayX*xInterval
    rangeEnd = rangeStart xInterval
    y = 0
    for date,sessions in sessions.items():
        for session in sessions:
            if session[0] < rangeEnd and session[0] session[1] > rangeStart:
                y  = 1
    heights.append(y)

# Plotting data
if heatmap:
    plt.yticks([])
    plt.imshow([heights], aspect="auto")
else:
    plt.plot(xAxis,heights)
    plt.ylim(ymin=0)
plt.xlim(xmin=0,xmax=len(heights))
plt.xlabel("Time of day")
plt.ylabel("How often I've coded at that time")
plt.xticks(timeTickLocations,timeTickLabels,
           fontsize=timeTickFontSize,rotation=timeTickRotation)
plt.show()

And here are some sample results

Graph produced by same configuration options shown in above code Graph produced by same configuration options shown in above code

Same data but as a line graph with a lower precision (24 per day) and more time ticks (48) Same data but as a line graph with a lower precision (24 per day) and more time ticks (48)

  • Related