Skip to content
Snippets Groups Projects
Commit f836583e authored by Kaur Huko Käämbre's avatar Kaur Huko Käämbre
Browse files

graph annotations

parent d343f073
No related branches found
No related tags found
No related merge requests found
......@@ -4,12 +4,13 @@ import math
displayed_percentiles = [90, 75, 50, 25, 10]
class ComputedData():
def __init__(self, year, temperatures, percentiles):
self.year = year
self.temperatures = temperatures
self.percentiles = percentiles
def is_float(value):
try:
value = float(value)
return True
except:
return False
def find_percentile(values, percentile):
sorted_values = values[:]
sorted_values.sort()
......@@ -23,97 +24,177 @@ def find_percentile(values, percentile):
return round((weight1 * sorted_values[index1]) + (weight2 * sorted_values[index2]), 2)
def percentiles_per_year(dataframe):
all_percentiles = dict()
means = []
for row in dataframe.iloc:
year = row[0]
temperature_cells = row[1:]
class Container:
def __init__(self, value):
self.value = value
class GraphData():
class TempsPerModel():
def __init__(self, years, temperatures):
self.years = years
self.temperatures = temperatures
def get_temperatures_per_model(self, df):
temperatures_per_model = []
years = df["Year"]
for header, column in df.items():
if (header == "Year"): continue
avail_years = []
avail_temps = []
for i in range(df.shape[0]):
temperature = column[i]
if not is_float(temperature): continue
avail_years.append(years[i])
avail_temps.append(float(temperature))
temperatures_per_model.append(GraphData.TempsPerModel(avail_years, avail_temps))
return temperatures_per_model
def get_percentiles_per_year(self, df):
percentiles_per_year = dict()
temperatures = []
for cell in temperature_cells:
try:
temperature = float(cell)
temperatures.append(temperature)
except: pass
for row in df.iloc:
year = row[0]
temperature_cells = row[1:]
all_percentiles[year] = [(p, find_percentile(temperatures, p)) for p in displayed_percentiles]
means.append(find_percentile(temperatures, 50))
temperatures = []
for cell in temperature_cells:
if (is_float(cell)):
temperatures.append(float(cell))
percentiles_per_year[year] = [(p, find_percentile(temperatures, p)) for p in displayed_percentiles]
return (all_percentiles, means)
def temperatures_per_model(dataframe):
all_temperatures = []
years = dataframe["Year"]
return percentiles_per_year
min_temp = math.inf
max_temp = -math.inf
for header, data in dataframe.items():
if (header == "Year"): continue
def get_means_per_year(self, df):
means_per_year = []
avail_years = []
avail_temps = []
for i in range(dataframe.shape[0]):
try:
temperature = float(data[i])
avail_years.append(years[i])
avail_temps.append(temperature)
min_temp = min(min_temp, temperature)
max_temp = max(max_temp, temperature)
except: pass
for row in df.iloc:
temperature_cells = row[1:]
all_temperatures.append((avail_years, avail_temps))
temperatures = []
for cell in temperature_cells:
if (is_float(cell)):
temperatures.append(float(cell))
means_per_year.append(find_percentile(temperatures, 50))
return means_per_year
return (all_temperatures, min_temp, max_temp)
def get_graph_corners(self, df):
years = df["Year"]
min_temp = math.inf
max_temp = -math.inf
for header, column in df.items():
if (header == "Year"): continue
for i in range(df.shape[0]):
temperature = column[i]
if not is_float(temperature): continue
min_temp = min(min_temp, float(temperature))
max_temp = max(max_temp, float(temperature))
return (years[0], min_temp, years[len(years)-1], max_temp)
def __init__(self, df):
self.temps_per_model = self.get_temperatures_per_model(df)
self.percentiles_per_year = self.get_percentiles_per_year(df)
self.means_per_year = self.get_means_per_year(df)
self.years = df["Year"]
(self.xmin, self.ymin, self.xmax, self.ymax) = self.get_graph_corners(df)
def get_hover_text(year, percentiles):
def get_hover_text(year, data):
percentiles_per_year = data.percentiles_per_year
year = round(year)
if not year in percentiles:
if not year in percentiles_per_year:
return None
text = f"{year}:"
for percentile in percentiles[year]:
text += f"\n{percentile[0]}th percentile: {percentile[1]}"
for percentiles in percentiles_per_year[year]:
text += f"\n{percentiles[0]}th percentile: {percentiles[1]}"
return text
def draw_graph(dataframe):
(all_temperatures, min_temp, max_temp) = temperatures_per_model(dataframe)
(percentiles, means) = percentiles_per_year(dataframe)
years = dataframe["Year"]
figure, (axes) = plt.subplots(1)
def draw_mouse_line(event, ax, data, mouse_line):
if (mouse_line.value != None):
mouse_line.value[0].remove()
for temps_per_model in all_temperatures:
axes.plot(temps_per_model[0], temps_per_model[1], linestyle="dashed", linewidth="0.5", color="#ff000055")
year = round(event.xdata)
year = max(data.xmin, year)
year = min(data.xmax, year)
axes.plot(years, means, linewidth="2", color="red")
mouse_line.value = ax.plot([year, year], [data.ymin, data.ymax], linewidth="1", color="#00000088")
def draw_hover_text(event, annotation, data):
year = event.xdata
year = max(data.xmin, year)
year = min(data.xmax, year)
axes.plot([2024, 2024], [min_temp, max_temp], linewidth="1", color="#00000088")
annotation.xy = (year, event.ydata)
annotation.set_text(get_hover_text(year, data))
if (year > 2024):
annotation.xyann = (-117, -50)
else:
annotation.xyann = (15, -50)
def on_mouse_move(event, figure, ax, annotation, data, mouse_line):
if not event.inaxes == ax:
return
annotation = axes.annotate(
draw_hover_text(event, annotation, data)
draw_mouse_line(event, ax, data, mouse_line)
figure.canvas.draw_idle()
def create_hover_annotation(figure, ax, data):
annotation = ax.annotate(
text = "",
xy = (0, 0),
xytext = (10, 10),
xytext = (0, 0),
textcoords = "offset points",
bbox = dict(boxstyle="round,pad=0.3", edgecolor="black", facecolor="white"),
bbox = dict(boxstyle="round,pad=0.5", edgecolor="#ffffff00", facecolor="#dddddddd"),
fontsize = 10,
visible = False
)
def on_motion_notify(event):
if event.inaxes == axes:
annotation.set_visible(True)
annotation.xy = (event.xdata, event.ydata)
annotation.set_text(get_hover_text(event.xdata, percentiles))
figure.canvas.draw_idle()
else:
annotation.set_visible(False)
mouse_line = Container(None)
annotation.set_visible(True)
figure.canvas.mpl_connect("motion_notify_event", lambda event: on_mouse_move(event, figure, ax, annotation, data, mouse_line))
figure.canvas.mpl_connect("motion_notify_event", on_motion_notify)
return annotation
def draw_graph(dataframe):
data = GraphData(dataframe)
figure, (ax) = plt.subplots(1)
# Draw temperatures of different models
for temperatures in data.temps_per_model:
ax.plot(temperatures.years, temperatures.temperatures, linestyle="dashed", linewidth="0.5", color="#ff000055")
# Draw median temperatures
test = ax.plot(data.years, data.means_per_year, linewidth="2", color="red")
# Line at current year
test2 = ax.plot([2024, 2024], [data.ymin, data.ymax], linewidth="1", color="#00000088")
create_hover_annotation(figure, ax, data)
plt.show()
......@@ -121,5 +202,4 @@ def main():
annual = pd.read_csv("data/annual.csv")
draw_graph(annual)
main()
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment