history.py 5.14 KB
Newer Older
sim-baz's avatar
sim-baz committed
1 2 3
import matplotlib.pyplot as plt
from cassandra.cluster import Cluster
from datetime import datetime
4 5 6 7 8 9
import numpy as np

import loading

table_name_space = loading.table_name_space
table_name_date = loading.table_name_date
sim-baz's avatar
sim-baz committed
10
numeric_columns = loading.numeric_columns
11

sim-baz's avatar
sim-baz committed
12 13
MIN_DATE = loading.MIN_DATE
MAX_DATE = loading.MAX_DATE
sim-baz's avatar
sim-baz committed
14 15

def getHistory(station, indicator):
sim-baz's avatar
sim-baz committed
16
	datas = session.execute(f"SELECT year, month, day, {indicator} FROM {table_name_space} where station = '{station}'")
sim-baz's avatar
sim-baz committed
17 18
	return datas

19
def getMeanByDay(table, dateMin, dateMax):
sim-baz's avatar
sim-baz committed
20
	# Dictionary to store sum of measures and number of measures by day
21 22
	table_date = {}
	for r in table:
sim-baz's avatar
sim-baz committed
23
		year = r[0]
sim-baz's avatar
sim-baz committed
24
		# Verify the measures is for the period chosen by user and have a value
25
		if year >= dateMin and year < dateMax and  r[len(r) - 1] != None:
sim-baz's avatar
sim-baz committed
26
			# convert attributes to date format as string
sim-baz's avatar
sim-baz committed
27
			date = str(r[0]) + "-" + "0" * (2 - len(str(r[1]))) + str(r[1]) + "-" + "0" * (2 - len(str(r[2]))) + str(r[2])
28 29 30 31
			if date not in table_date.keys():
				table_date[date] = 0,0
			table_date[date] = (table_date[date][0] + r[len(r) - 1], table_date[date][1] + 1)

sim-baz's avatar
sim-baz committed
32
	# Treat datas to get mean by day
33 34
	for d in table_date.keys():
		table_date[d] = table_date[d][0] / table_date[d][1]
sim-baz's avatar
sim-baz committed
35

36 37 38
	return table_date

def getMeanByMonth(table):
sim-baz's avatar
sim-baz committed
39
	# Dictionary to store sum of measures and number of measures by month
40 41
	table_month = {}
	for r in table:
sim-baz's avatar
sim-baz committed
42
		# Verify the value of measure (needs to have a value)
43
		if r[len(r) - 1] != None:
sim-baz's avatar
sim-baz committed
44
			month = r[1]
45 46 47 48
			if month not in table_month.keys():
				table_month[month] = 0,0
			table_month[month] = (table_month[month][0] + r[len(r) - 1], table_month[month][1] + 1)

sim-baz's avatar
sim-baz committed
49
	# Treat datas to get mean by month
50 51 52 53 54
	for d in table_month.keys():
		table_month[d] = table_month[d][0] / table_month[d][1]

	return table_month

sim-baz's avatar
sim-baz committed
55 56 57 58 59 60 61 62 63 64 65 66 67
# Verify the validity of the years given
def verifyYearValidity(dateMin, dateMax):
	# Verification to ensure the validity of parameters, dates not equal
	if dateMin == dateMax:
		print(f"Les dates ne doivent pas être égales")
		return False

	# Verification to ensure the validity of parameters, dates in the right period
	if dateMin < MIN_DATE or dateMin > (MAX_DATE + 1) or dateMax < MIN_DATE or dateMax > (MAX_DATE + 1):
		print(f"Les dates doivent être comprises entre {MIN_DATE} et {MAX_DATE}")
		return False
	return True

68
def plotHistory(station, indicator, dateMin, dateMax):
sim-baz's avatar
sim-baz committed
69
	# Accept only indicator with numeric values (not factors)
sim-baz's avatar
sim-baz committed
70
	if indicator in numeric_columns:
sim-baz's avatar
sim-baz committed
71
		if not verifyYearValidity(dateMin, dateMax):
72 73
			return

sim-baz's avatar
sim-baz committed
74
		# Get datas from cassandra table
sim-baz's avatar
sim-baz committed
75
		table = getHistory(station, indicator)
76
		table = list(table)
sim-baz's avatar
sim-baz committed
77

sim-baz's avatar
sim-baz committed
78
		# If no data for the period selected
sim-baz's avatar
sim-baz committed
79
		if not table:
sim-baz's avatar
sim-baz committed
80
			print(f"Aucune donnée pour la station {station} et pour l'indicateur {indicator} et pour la période {dateMin} - {dateMax}")
sim-baz's avatar
sim-baz committed
81 82
			return

sim-baz's avatar
sim-baz committed
83
		# Treat datas
84 85
		table_mean = getMeanByDay(table, dateMin, dateMax)
		table_mean_by_month = getMeanByMonth(table)
sim-baz's avatar
sim-baz committed
86 87 88
		if not table_mean or not table_mean_by_month:
			print(f"Aucune donnée pour la station {station} et pour l'indicateur {indicator} et pour la période {dateMin} - {dateMax}")
			return
sim-baz's avatar
sim-baz committed
89

sim-baz's avatar
sim-baz committed
90
		# Duplicate list for each year in the period required
91 92 93 94 95
		liste = []
		for i in range(dateMax - dateMin):
			for key,value in table_mean_by_month.items():
				liste.append([key, value])

sim-baz's avatar
sim-baz committed
96
		# Completing the month to have a date format (yyyy-month-01)
97 98 99 100 101 102 103 104 105 106
		i = dateMin
		j = 1
		for k in range(len(liste)):
			j += 1
			liste[k][0] = str(i) + '-' + str(liste[k][0])
			if j > 12:
				i += 1
				j = 1

		# Name for file
sim-baz's avatar
sim-baz committed
107 108 109
		currentDateTime = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
		file_name = str(currentDateTime) + "_" + station + "_" + indicator + ".png"

sim-baz's avatar
sim-baz committed
110 111
		# Configure graduation of plot
		# Need to find a nice step for graduation (no more than 6 values to be understandable)
112
		step_graduation = max((dateMax - dateMin) // 5, 1)
sim-baz's avatar
sim-baz committed
113
		# Convert the graduation to the date format (yyyy-month-01)
114
		graduation = ["20" + "0" * (2 - len(str(i))) + str(i) + "-01-01" for i in range(int(str(dateMin)[2:4]), int(str(dateMax)[2:4]), step_graduation)]
sim-baz's avatar
sim-baz committed
115
		# Add the last value of graduation for the last day of measures
116
		graduation.append("20" + "0" * (2 - len(str(dateMax - 1)[2:4])) + str(dateMax - 1)[2:4] + "-12-31")
sim-baz's avatar
sim-baz committed
117
		
sim-baz's avatar
sim-baz committed
118
		# Plot, with both measures and season mean
119
		fig, ax1 = plt.subplots()
sim-baz's avatar
sim-baz committed
120
		# Measures on axis 1
121 122 123
		ax1.plot_date(table_mean.keys(), table_mean.values(), '-', xdate = True)
		ax1.xaxis.set_ticks(graduation)
		ax2 = ax1.twiny()
sim-baz's avatar
sim-baz committed
124
		# Seasonal mean
125
		ax2.plot([elt[0] for elt in liste], [elt[1] for elt in liste], '-', color = "r")
sim-baz's avatar
sim-baz committed
126
		# Do not show graduation on the top of the plot
127 128
		ax2.xaxis.set_ticks([])

sim-baz's avatar
sim-baz committed
129
		# Set title and labels
sim-baz's avatar
sim-baz committed
130 131 132
		plt.title(f"Evolution de {indicator} pour la station {station}")
		plt.xlabel('Date')
		plt.ylabel(indicator)
133 134 135 136 137 138
		plt.tick_params(
		    axis='x',
		    which='both',
		    bottom=False,
		    top=True
		)
sim-baz's avatar
sim-baz committed
139
		# Save figure
sim-baz's avatar
sim-baz committed
140
		plt.savefig(file_name)
141
		print(f"Le graphique a été enregistré à {file_name}")
sim-baz's avatar
sim-baz committed
142

sim-baz's avatar
sim-baz committed
143 144 145
	else:
		print("Les données pour cet indicateur ne sont pas numériques, impossible de tracer un graphique")

sim-baz's avatar
sim-baz committed
146
if __name__ == '__main__':
sim-baz's avatar
sim-baz committed
147 148 149 150
	cluster = Cluster()
	session = cluster.connect()
	session.set_keyspace("bazinsim_roisinos_metar")

sim-baz's avatar
sim-baz committed
151
	print()
sim-baz's avatar
sim-baz committed
152
	plotHistory("EFKI", "tmpf", 2001, 2004)
sim-baz's avatar
sim-baz committed
153
	print()