new graph drawing backend

This commit is contained in:
pseusys
2023-02-13 01:27:28 +01:00
parent 9191cbf8d2
commit f58bd419ba
3 changed files with 53 additions and 97 deletions

5
loc.py
View File

@@ -10,7 +10,7 @@ from io import StringIO, BytesIO
from dotenv import load_dotenv from dotenv import load_dotenv
import time import time
from make_bar_graph import BarGraph from make_bar_graph import build_graph
class LinesOfCode: class LinesOfCode:
@@ -34,8 +34,7 @@ class LinesOfCode:
return yearly_data return yearly_data
def plotLoc(self, yearly_data): def plotLoc(self, yearly_data):
graph = BarGraph(yearly_data) build_graph(yearly_data)
graph.build_graph()
self.pushChart() self.pushChart()
def run_query_v3(self, endPoint): def run_query_v3(self, endPoint):

View File

@@ -1,106 +1,68 @@
import os from typing import Dict
import pandas as pd from os.path import join, dirname
from json import load
import numpy as np import numpy as np
import altair as alt import matplotlib.patches as mpatches
import json import matplotlib.pyplot as plt
import os
# npm install vega-lite vega-cli canvas
class BarGraph: MAX_LANGUAGES = 5
def __init__(self, yearly_data):
self.yearly_data = yearly_data
def build_graph(self): def build_graph(yearly_data: Dict) -> str:
"""
Draws graph of lines of code written by user by quarters of years.
Picks top `MAX_LANGUAGES` languages from each quarter only.
with open(os.path.join(os.path.dirname(__file__), 'colors.json')) as f: :param yearly_data: GitHub user yearly data.
colors = json.load(f) :return: String, path to graph file.
allColorsValues = [] """
with open(join(dirname(__file__), "colors.json")) as f:
colors = load(f)
# filter data languages_all_loc = dict()
max_languages = 5 years = len(yearly_data.keys())
top_languages = {} year_indexes = np.arange(years)
for year in self.yearly_data.keys():
for quarter in self.yearly_data[year].keys():
for language in sorted(list(self.yearly_data[year][quarter].keys()),
key=lambda lang: self.yearly_data[year][quarter][lang], reverse=True)[
0:max_languages]:
if 'top' not in self.yearly_data[year][quarter]:
self.yearly_data[year][quarter]['top'] = {}
if self.yearly_data[year][quarter][language] != 0:
self.yearly_data[year][quarter]['top'][language] = self.yearly_data[year][quarter][language]
if language not in top_languages: for i, y in enumerate(sorted(yearly_data.keys())):
top_languages[language] = 1 for q in yearly_data[y].keys():
top_languages[language] += 1 langs = sorted(yearly_data[y][q].keys(), key=lambda l: yearly_data[y][q][l], reverse=True)[0:MAX_LANGUAGES]
# print(self.yearly_data) for lang in langs:
if lang not in languages_all_loc:
languages_all_loc[lang] = np.array([[0] * years] * 4)
languages_all_loc[lang][q - 1][i] = yearly_data[y][q][lang]
all_languages = list(top_languages.keys()) fig = plt.figure()
ax = fig.add_axes([0, 0, 1.5, 1])
for language in all_languages: language_handles = []
if colors[language]['color'] is not None: cumulative = np.array([[0] * years] * 4)
allColorsValues.append(colors[language]['color'])
languages_all_loc = {} for key, value in languages_all_loc.items():
color = colors[key]["color"] if colors[key]["color"] is not None else "w"
language_handles += [mpatches.Patch(color=color, label=key)]
for language in all_languages: for quarter in range(4):
language_year = [] ax.bar(year_indexes + quarter * 0.21, value[quarter], 0.2, bottom=cumulative[quarter], color=color)
for year in self.yearly_data.keys(): cumulative[quarter] = np.add(cumulative[quarter], value[quarter])
language_quarter = [0, 0, 0, 0]
for quarter in self.yearly_data[year].keys():
if language in self.yearly_data[year][quarter]['top']:
language_quarter[quarter - 1] = self.yearly_data[year][quarter]['top'][language]
else:
language_quarter[quarter - 1] = 0
language_year.append(language_quarter)
languages_all_loc[language] = language_year
# print(languages_all_loc) ax.set_ylabel("LOC added", fontdict=dict(weight="bold"))
ax.set_xticks(np.array([np.arange(i, i + 0.84, step=0.21) for i in year_indexes]).flatten(), labels=["Q1", "Q2", "Q3", "Q4"] * years)
language_df = {} sax = ax.secondary_xaxis("top")
sax.set_xticks(year_indexes + 0.42, labels=sorted(yearly_data.keys()))
sax.spines["top"].set_visible(False)
def prep_df(df, name): ax.legend(title="Language", handles=language_handles, loc="upper left", bbox_to_anchor=(1, 1), framealpha=0, title_fontproperties=dict(weight="bold"))
df = df.stack().reset_index()
df.columns = ['c1', 'c2', 'values']
df['Language'] = name
return df
for language in languages_all_loc.keys(): sax.tick_params(axis="both", length=0)
language_df[language] = pd.DataFrame(languages_all_loc[language], index=list(self.yearly_data.keys()), sax.spines["top"].set_visible(False)
columns=["Q1", "Q2", "Q3", "Q4"]) ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
for language in language_df.keys(): plt.ylim(0, 1.05 * np.amax(cumulative))
language_df[language] = prep_df(language_df[language], language) plt.savefig("bar_graph.png", bbox_inches="tight")
plt.close(fig)
df = pd.concat(language_df.values()) return "bar_graph.png"
chart = alt.Chart(df).mark_bar().encode(
# tell Altair which field to group columns on
x=alt.X('c2:N', title=None),
# tell Altair which field to use as Y values and how to calculate
y=alt.Y('sum(values):Q',
axis=alt.Axis(
grid=False,
title='LOC added')),
# tell Altair which field to use to use as the set of columns to be represented in each group
column=alt.Column('c1:N', title=None),
# tell Altair which field to use for color segmentation
color=alt.Color('Language:N',
scale=alt.Scale(
domain=all_languages,
# make it look pretty with an enjoyable color pallet
range=allColorsValues,
),
)) \
.configure_view(
# remove grid lines around column clusters
strokeOpacity=0
)
chart.save('bar_graph.png')
return 'bar_graph.png'

View File

@@ -1,7 +1,3 @@
altair==4.1.0
altair-data-server==0.4.1
altair-saver==0.5.0
altair-viewer==0.3.0
attrs==20.3.0 attrs==20.3.0
certifi==2020.12.5 certifi==2020.12.5
chardet==4.0.0 chardet==4.0.0
@@ -14,9 +10,8 @@ Jinja2==2.11.3
jsonschema==3.2.0 jsonschema==3.2.0
kiwisolver==1.3.1 kiwisolver==1.3.1
MarkupSafe==1.1.1 MarkupSafe==1.1.1
matplotlib==3.4.1 matplotlib==3.6.3
numpy==1.20.2 numpy==1.20.2
pandas==1.2.3
Pillow==8.2.0 Pillow==8.2.0
portpicker==1.3.1 portpicker==1.3.1
PyGithub==1.54.1 PyGithub==1.54.1