def make_plot(channel, time, drawLabels=True): #get the log file directory = "logs/" + channel + '/' + time filename = 'rate.csv' file_path = os.path.relpath(directory + '/' + filename) with open(file_path, 'r') as rate: rates = map(lambda x: x.strip(), list(rate)) start_hour = int(rates[0].split('=')[1].split('_')[0]) start_min = int(rates[0].split('=')[1].split('_')[1]) #Load data rates = rates[1:] events = [] to_delete = [] for rate in rates: if len(rate.split('*')) >= 3: events.append((int(rate.split('*')[1]), rate.split(',', 1)[1])) to_delete.append(rate) rates = [x for x in rates if x not in to_delete] old_len = len(rates) rates = remove_trailing_zeroes(rates) num_removed = old_len - len(rates) mins = map( lambda x: int( filter(lambda x: x in string.printable, x).split(',')[0]), rates) ##### XXX l = len(mins) mins = [] for i in range(l): mins.append(i) ##### XXX y_data = map(lambda x: float(x.split(',')[1]), rates) show_viewers = False try: y_data2 = map(lambda x: int(x.split(',')[2]), rates) show_viewers = True except IndexError: print rates pass dur = mins[-1] + 1 #in minutes #interval = 15 interval = get_xinterval(dur) padding_mins = start_min % interval carry = start_min / interval x_data = range(carry * interval, start_min + dur + min(num_removed, padding_mins)) x = np.array(x_data) y = np.random.randint(1, size=padding_mins) #pad it with all 0's y = np.append(y, np.array(y_data)) y = np.append(y, np.random.randint(1, size=min( num_removed, padding_mins))) #potentially add zeroes to the end if show_viewers: y2 = np.random.randint(1, size=padding_mins) #pad it with all 0's y2 = np.append(y2, np.array(y_data2)) y2 = np.append( y2, np.random.randint( 1, size=min(num_removed, padding_mins))) #potentially add zeroes to the end #print len(x) #print len(y) #print len(y2) times = time.split('-') #2014-08-23-04AM try: year = int(times[0]) mo = int(times[1]) day = int(times[2]) hour = start_hour minute = start_min minute = 0 #????????????????????????????????????????????????????????????? start_time = datetime.datetime(year, mo, day, hour, minute, 0) except ValueError: #debugging. print "THIS SHOULD NEVER HAPPEN! Email me [email protected] right away!" start_time = datetime.datetime(2014, 8, 11, start_hour, start_min) #Removes leading zeroes from all the "words" in s. #"00138 hello 01AM" -> "138 hello 1AM" def removeLeadingZeroes(s): return " ".join(map(lambda x: x.lstrip('0'), s.split(" "))) def formatTime(x, pos): #timestamp = (start_time - datetime.datetime(1970, 1, 1)).total_seconds() + x*60 #now_time = datetime.datetime.fromtimestamp(timestamp) #does not convert time zones. Need time zones. now_time = datetime.timedelta(hours=float(x) / 60) + start_time if dur > 2160: #Aug 5, 8AM return removeLeadingZeroes(now_time.strftime("%b %d, %I %p")) elif interval >= 60: #8AM return removeLeadingZeroes(now_time.strftime("%I %p")) else: #7:45 AM return removeLeadingZeroes(now_time.strftime("%I:%M %p")) print "Drawing rate over time graph..." #START GRAPHING #plt.figure(num=None, figsize=(36, 16), dpi=80) plt.figure(num=None, figsize=(27, 12), dpi=80) #fig, ax = plt.subplots() ax = plt.axes() ax.xaxis.grid(True) ax.xaxis.set_major_formatter(FuncFormatter(formatTime)) ax.yaxis.grid(True) ax.grid(True) r = 45 if dur >= 2160: r = 270 plt.xticks(np.arange(min(x), max(x) + 1, interval), rotation=r) months = [ '', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] try: i = int(times[1]) mon = months[i] ye = int(times[2]) da = int(times[0]) plt.title("%s - %s %d, %d\n" % (channel, mon, ye, da)) except (ValueError, IndexError): plt.title(channel + '\n') settingsDict = getSettings() local_timezone = None try: local_timezone = settingsDict['timezone'] except KeyError as e: print "Setting missing:", e raise except ValueError as e: print "Malformed setting:", e raise if local_timezone.lower().strip() == 'none' or local_timezone.lower( ).strip() == 'auto': local_timezone = datetime.datetime.now( tzlocal()).tzname() #Eastern Daylight Time else: local_timezone = local_timezone.strip() split = local_timezone.split(" ") if len(split) > 1: local_timezone = "".join([word[0] for word in split]) avg_mpm = np.mean(y) plt.xlabel('\nTimes in ' + local_timezone) plt.ylabel('\nMessages per minute (Avg=%0.2f)\n' % avg_mpm, color='blue') for tl in ax.get_yticklabels(): tl.set_color('blue') plt.plot(x, y, linewidth=2, color='#4422AA') if show_viewers: ax2color = 'green' ax2 = ax.twinx() ax2.plot(x, y2, linewidth=4, color=ax2color) ax2.fill_between(x, 0, y2, color=ax2color, alpha=0.1) ax2.set_frame_on(True) ax2.patch.set_visible(False) ax2.yaxis.set_ticks_position('right') ax2.yaxis.set_label_position('right') avg_viewercount = np.mean(y2) ax2.set_ylabel('Viewercount (Avg=%0.1f)\n\n' % avg_viewercount, color=ax2color, labelpad=50, rotation=270) m = 1.16 * max(y) m2 = 1.16 * max(y2) ax.set_yticks(np.arange(0, m, get_yinterval(max(y)))) ax2.set_yticks(np.arange(0, m2, get_yinterval(max(y2)))) ax.set_ylim(0, m) ax2.set_ylim(0, m2) for tl in ax2.get_yticklabels(): tl.set_color(ax2color) ax.fill_between(x, 0, y, color='#5577DD') font = {'size': 25} rc('font', **font) ticklist = ax2.get_yticks() height_diff = ticklist[1] - ticklist[0] height_offset = ticklist[1] init_offset = height_offset ha = 'center' for event in events: if drawLabels: plt.axvline(x=event[0] + padding_mins + carry * interval, color='red', linewidth=2, label=event[1]) s = event[1].replace('\\n', '\n') down = ax2.yaxis.get_view_interval()[1] - height_offset plt.text( event[0] + padding_mins + carry * interval, down, s, color='red', verticalalignment='top', horizontalalignment=ha, fontsize=25, rotation=0, #rotation=270, path_effects=[PathEffects.withSimplePatchShadow(linewidth=2)]) #path_effects=[PathEffects.withStroke(linewidth=1,foreground="black")]) height_offset = ( height_offset + height_diff) if height_offset == init_offset else init_offset #height_offset = height_diff - height_offset #S E L L O U T plt.text(0.01, 0.99, 'github.com/popcorncolonel/chat_stats', color='#666666', verticalalignment='top', horizontalalignment='left', fontsize=25, rotation=0, transform=ax.transAxes) plt.text(0.99, 0.99, 'http://twitch.tv/' + channel, color='#666666', verticalalignment='top', horizontalalignment='right', fontsize=25, rotation=0, transform=ax.transAxes) #plt.text(-0.05, -0.170, 'http://github.com/popcorncolonel/chat_stats', color='grey', verticalalignment='top', # horizontalalignment='left', fontsize=25, rotation=0, transform=ax.transAxes) #plt.text(1.05, -0.170, 'http://www.twitch.tv/'+channel, color='grey', verticalalignment='top', # horizontalalignment='right', fontsize=25, rotation=0, transform=ax.transAxes) #plt.show() #for running locally rather than saving the figure directory = "images/" + channel + '/' + time if not os.path.exists(directory): os.makedirs(directory) plt.savefig(directory + '/rate.png', bbox_inches='tight') print "Rate graph completed!"
from thread import start_new_thread, exit import os import sys import time import string import datetime import threading import urllib2 import json import re from twitch_chat_listen import listen #py2exe is weird. from get_settings import getSettings settingsDict = getSettings() #converts string to boolean def toBool(s): try: return s.lower().strip() in ['true', 'yes', 'y', '1', 't', 'yeah'] except AttributeError, ValueError: return False try: include_emotes = toBool(settingsDict['include_emotes']) create_graph = toBool(settingsDict['create_graph']) create_wordcloud = toBool(settingsDict['create_wordcloud']) verbose = toBool(settingsDict['verbose']) debug = toBool(settingsDict['debug']) except KeyError as e:
def make_plot(channel, time, drawLabels=True): # get the log file directory = "logs/" + channel + "/" + time filename = "rate.csv" file_path = os.path.relpath(directory + "/" + filename) with open(file_path, "r") as rate: rates = map(lambda x: x.strip(), list(rate)) start_hour = int(rates[0].split("=")[1].split("_")[0]) start_min = int(rates[0].split("=")[1].split("_")[1]) # Load data rates = rates[1:] events = [] to_delete = [] for rate in rates: if len(rate.split("*")) >= 3: events.append((int(rate.split("*")[1]), rate.split(",", 1)[1])) to_delete.append(rate) rates = [x for x in rates if x not in to_delete] old_len = len(rates) rates = remove_trailing_zeroes(rates) num_removed = old_len - len(rates) mins = map(lambda x: int(filter(lambda x: x in string.printable, x).split(",")[0]), rates) ##### XXX l = len(mins) mins = [] for i in range(l): mins.append(i) ##### XXX y_data = map(lambda x: float(x.split(",")[1]), rates) show_viewers = False try: y_data2 = map(lambda x: int(x.split(",")[2]), rates) show_viewers = True except IndexError: print rates pass dur = mins[-1] + 1 # in minutes # interval = 15 interval = get_xinterval(dur) padding_mins = start_min % interval carry = start_min / interval x_data = range(carry * interval, start_min + dur + min(num_removed, padding_mins)) x = np.array(x_data) y = np.random.randint(1, size=padding_mins) # pad it with all 0's y = np.append(y, np.array(y_data)) y = np.append(y, np.random.randint(1, size=min(num_removed, padding_mins))) # potentially add zeroes to the end if show_viewers: y2 = np.random.randint(1, size=padding_mins) # pad it with all 0's y2 = np.append(y2, np.array(y_data2)) y2 = np.append( y2, np.random.randint(1, size=min(num_removed, padding_mins)) ) # potentially add zeroes to the end # print len(x) # print len(y) # print len(y2) times = time.split("-") # 2014-08-23-04AM try: year = int(times[0]) mo = int(times[1]) day = int(times[2]) hour = start_hour minute = start_min minute = 0 # ????????????????????????????????????????????????????????????? start_time = datetime.datetime(year, mo, day, hour, minute, 0) except ValueError: # debugging. print "THIS SHOULD NEVER HAPPEN! Email me [email protected] right away!" start_time = datetime.datetime(2014, 8, 11, start_hour, start_min) # Removes leading zeroes from all the "words" in s. # "00138 hello 01AM" -> "138 hello 1AM" def removeLeadingZeroes(s): return " ".join(map(lambda x: x.lstrip("0"), s.split(" "))) def formatTime(x, pos): # timestamp = (start_time - datetime.datetime(1970, 1, 1)).total_seconds() + x*60 # now_time = datetime.datetime.fromtimestamp(timestamp) #does not convert time zones. Need time zones. now_time = datetime.timedelta(hours=float(x) / 60) + start_time if dur > 2160: # Aug 5, 8AM return removeLeadingZeroes(now_time.strftime("%b %d, %I %p")) elif interval >= 60: # 8AM return removeLeadingZeroes(now_time.strftime("%I %p")) else: # 7:45 AM return removeLeadingZeroes(now_time.strftime("%I:%M %p")) print "Drawing rate over time graph..." # START GRAPHING # plt.figure(num=None, figsize=(36, 16), dpi=80) plt.figure(num=None, figsize=(27, 12), dpi=80) # fig, ax = plt.subplots() ax = plt.axes() ax.xaxis.grid(True) ax.xaxis.set_major_formatter(FuncFormatter(formatTime)) ax.yaxis.grid(True) ax.grid(True) r = 45 if dur >= 2160: r = 270 plt.xticks(np.arange(min(x), max(x) + 1, interval), rotation=r) months = [ "", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ] try: i = int(times[1]) mon = months[i] ye = int(times[2]) da = int(times[0]) plt.title("%s - %s %d, %d\n" % (channel, mon, ye, da)) except (ValueError, IndexError): plt.title(channel + "\n") settingsDict = getSettings() local_timezone = None try: local_timezone = settingsDict["timezone"] except KeyError as e: print "Setting missing:", e raise except ValueError as e: print "Malformed setting:", e raise if local_timezone.lower().strip() == "none" or local_timezone.lower().strip() == "auto": local_timezone = datetime.datetime.now(tzlocal()).tzname() # Eastern Daylight Time else: local_timezone = local_timezone.strip() split = local_timezone.split(" ") if len(split) > 1: local_timezone = "".join([word[0] for word in split]) avg_mpm = np.mean(y) plt.xlabel("\nTimes in " + local_timezone) plt.ylabel("\nMessages per minute (Avg=%0.2f)\n" % avg_mpm, color="blue") for tl in ax.get_yticklabels(): tl.set_color("blue") plt.plot(x, y, linewidth=2, color="#4422AA") if show_viewers: ax2color = "green" ax2 = ax.twinx() ax2.plot(x, y2, linewidth=4, color=ax2color) ax2.fill_between(x, 0, y2, color=ax2color, alpha=0.1) ax2.set_frame_on(True) ax2.patch.set_visible(False) ax2.yaxis.set_ticks_position("right") ax2.yaxis.set_label_position("right") avg_viewercount = np.mean(y2) ax2.set_ylabel("Viewercount (Avg=%0.1f)\n\n" % avg_viewercount, color=ax2color, labelpad=50, rotation=270) m = 1.16 * max(y) m2 = 1.16 * max(y2) ax.set_yticks(np.arange(0, m, get_yinterval(max(y)))) ax2.set_yticks(np.arange(0, m2, get_yinterval(max(y2)))) ax.set_ylim(0, m) ax2.set_ylim(0, m2) for tl in ax2.get_yticklabels(): tl.set_color(ax2color) ax.fill_between(x, 0, y, color="#5577DD") font = {"size": 25} rc("font", **font) ticklist = ax2.get_yticks() height_diff = ticklist[1] - ticklist[0] height_offset = ticklist[1] init_offset = height_offset ha = "center" for event in events: if drawLabels: plt.axvline(x=event[0] + padding_mins + carry * interval, color="red", linewidth=2, label=event[1]) s = event[1].replace("\\n", "\n") down = ax2.yaxis.get_view_interval()[1] - height_offset plt.text( event[0] + padding_mins + carry * interval, down, s, color="red", verticalalignment="top", horizontalalignment=ha, fontsize=25, rotation=0, # rotation=270, path_effects=[PathEffects.withSimplePatchShadow(linewidth=2)], ) # path_effects=[PathEffects.withStroke(linewidth=1,foreground="black")]) height_offset = (height_offset + height_diff) if height_offset == init_offset else init_offset # height_offset = height_diff - height_offset # S E L L O U T plt.text( 0.01, 0.99, "github.com/popcorncolonel/chat_stats", color="#666666", verticalalignment="top", horizontalalignment="left", fontsize=25, rotation=0, transform=ax.transAxes, ) plt.text( 0.99, 0.99, "http://twitch.tv/" + channel, color="#666666", verticalalignment="top", horizontalalignment="right", fontsize=25, rotation=0, transform=ax.transAxes, ) # plt.text(-0.05, -0.170, 'http://github.com/popcorncolonel/chat_stats', color='grey', verticalalignment='top', # horizontalalignment='left', fontsize=25, rotation=0, transform=ax.transAxes) # plt.text(1.05, -0.170, 'http://www.twitch.tv/'+channel, color='grey', verticalalignment='top', # horizontalalignment='right', fontsize=25, rotation=0, transform=ax.transAxes) # plt.show() #for running locally rather than saving the figure directory = "images/" + channel + "/" + time if not os.path.exists(directory): os.makedirs(directory) plt.savefig(directory + "/rate.png", bbox_inches="tight") print "Rate graph completed!"
#TODO? Make emote cloud the actual pictures of the emotes? How bad of an idea is that. I don't know. import os import sys import datetime import random import urllib2 try: import wordcloud except ImportError: print "Looks like you're missing one of the wordcloud dependencies - Check the Github page at https://github.com/popcorncolonel/chat_stats to see what you need to install." raise from get_settings import getSettings settingsDict = getSettings() try: w_words = int(settingsDict['w_words']) h_words = int(settingsDict['h_words']) w_emotes = int(settingsDict['w_emotes']) h_emotes = int(settingsDict['h_emotes']) except KeyError as e: print "Setting missing:", e raise except ValueError as e: print "Malformed setting:", e raise def make_cloud(channel, time, myType=None, drawLabels=True, font_path=None): #get the log file directory = "logs/" + channel + '/' + time