File size: 10,929 Bytes
00ac9b2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
#standard imports
import pandas as pd
import numpy as np
import streamlit as st
import os
import glob


#imports for finding the nearest lat long using haversine distance
from math import radians, cos, sin, asin, sqrt
import math

#visualization libraries to visualize different plots
import plotly.express as px
import plotly.graph_objects as go
import altair as alt


#for Logo plotting
from PIL import Image

#for Folium Map Creation
from typing import Dict, List, Optional
import folium
from streamlit_folium import st_folium
from branca.element import Figure
from precipitation_function import lat_long_type

#disabling warnings
import warnings
warnings.filterwarnings("ignore")

#For parallel processing
from pandarallel import pandarallel
pandarallel.initialize(progress_bar=True)



fig = Figure(width = 550,height = 350)

#function for calculating annual average
@st.cache
def annual_avg(df,year_lst):
    annual_avg_df_lst = list()
    for i in year_lst:
        d = df.get_group((i))
        d['Annual avg'] = (d['daily_avg'].sum())/len(d)
        annual_avg_df_lst.append(d)
    return annual_avg_df_lst


#function for splitting the date column values into year, month and day
def df_date_split(df,lat_long_list):
    df_date_list = list()
    for i in lat_long_list:
        grouped_df = df.get_group(i)
        grouped_df[['Year','Month','Day']] = grouped_df['date'].str.split('-',expand = True)
        df_date_list.append(grouped_df)
    date_split_df = pd.concat(df_date_list)
    return date_split_df


@st.cache
#function for creating 2 separate columns one for country code with 'et' values and 2nd with lat long concated values
def lat_long_process(df):
    df['lat_long'] = df.loc[:,'lat'].astype(str)+','+df.loc[:,'long'].astype(str)
    df.drop_duplicates(inplace = True)
    return df

@st.cache
#Creating a separate dataframe for lat long values and returning a list of lat_long values
def lat_long_list_creation(df):
    lat_long_df = df[['lat','long']]
    lat_long_df['lat_long'] = lat_long_df.loc[:,'lat'].astype(str)+','+lat_long_df.loc[:,'long'].astype(str)
    lat_long_df.drop_duplicates(inplace=True)
    lat_long_list = lat_long_df['lat_long']
    return lat_long_list


#function for grouping the data on lat long and returning only the et lat long
def group_df(df,lat_long_lst):
    in_names = df.groupby(df['lat_long'])
    temperaturedf_new = list()
    for i in lat_long_lst:
        df1 = in_names.get_group(i)
        temperaturedf_new.append(df1)
    result = pd.concat(temperaturedf_new)
    return result


#function for calculating daily average
def daily_avg(x,y):
    return (x+y)/2



@st.cache
#creating avg dataframe
def annual_avg_plot(annual_avg_df,lat_long_option,lat_long_list):
    annual_avg_df = annual_avg_df.groupby('lat_long')
    annual_avg_df = df_date_split(annual_avg_df,lat_long_list)
    annual_avg_df = annual_avg_df.groupby('lat_long')
    annual_avg_df = annual_avg_df.get_group(lat_long_option)
    #returns the list of unique year values
    year_lst = annual_avg_df['Year'].unique()
    annual_avg_dataframe = annual_avg_df.groupby('Year')
    annual_avg_result = annual_avg(annual_avg_dataframe,year_lst)
    annual_average = pd.concat(annual_avg_result,axis = 0)
    return annual_average


#creating average temp plotly chart
def avg_temp_plot(annual_temp,lat_long_val):
    #CODE FOR PLOTTING ANNUAL AVERAGE TEMPERATURE
    fig_avg = px.line(annual_temp, x= 'Year',y='Annual avg')
    fig_avg.update_layout(
    yaxis = dict(tickfont = dict(size=15)),
    xaxis = dict(tickfont = dict(size=15)),
    plot_bgcolor = 'rgba(0,0,0,0)')
    fig_avg.update_traces(line_color ='dimgray')
    fig_avg.update_xaxes(gridcolor='whitesmoke')
    fig_avg.update_yaxes(gridcolor = 'whitesmoke')
    fig_avg.update_yaxes(title = 'Annual Average Temperature (C)')
    # fig_avg.update_layout(title = "Annual Average Temperature: "+str(lat_long_val))

    return fig_avg


@st.cache
def annual_min_plot(Annual_temp_min,option_annual_min_temp,lat_long_list):
    Annual_temp_min = Annual_temp_min.groupby('lat_long')
    Annual_temp_min = df_date_split(Annual_temp_min,lat_long_list)
    Annual_temp_min = Annual_temp_min.groupby(['lat_long','Year'])[['tmin']].min()
    Annual_temp_min.rename(columns = {'tmin':'Yearly_minimum_temp'},inplace = True)
    Annual_temp_min.reset_index(inplace = True)
    Annual_temp_min = Annual_temp_min.groupby('lat_long')
    df2 = Annual_temp_min.get_group(option_annual_min_temp)
    return df2

@st.cache
def annual_max_plot(Annual_temp,option_annual_temp,lat_long_list):
    Annual_temp = Annual_temp.groupby('lat_long')
    Annual_temp = df_date_split(Annual_temp,lat_long_list)
    Annual_temp = Annual_temp.groupby(['lat_long','Year'])[['tmax']].max()
    Annual_temp.rename(columns = {'tmax':'Yearly_maximum_temp'},inplace = True)
    Annual_temp.reset_index(inplace = True)
    Annual_temp = Annual_temp.groupby('lat_long')
    df1 = Annual_temp.get_group(option_annual_temp)
    return df1


@st.cache
def daily_avg_calc(result,option,start,end):
    grouped_temperature_df = result.groupby('lat_long')
    data_frame = grouped_temperature_df.get_group(option)
    data_frame.set_index('date',inplace = True)
    data_frame_start_end = data_frame.loc[str(start):str(end)]
    data_frame_start_end = data_frame_start_end.reset_index()
    return data_frame_start_end

def daily_avg_plot(data_frame_start_end,lat_long_val):
    #Plotting the line chart of the daily average
    fig  = px.line(data_frame_start_end, x = 'date',y='daily_avg',title = 'Daily Average Temperature')
    fig.update_traces(line_color = 'blue')
    fig.update_xaxes(title_text = 'Year',gridcolor = 'whitesmoke')
    fig.update_yaxes(ticklabelposition="inside top", title= 'Daily Average Temperature (C)',gridcolor = 'whitesmoke')
    fig.update_layout(margin = dict(l=25,r=25,t=25,b=25))
    fig.update_layout(plot_bgcolor = 'rgba(0,0,0,0)')
    # fig.update_layout(title = "Daily Average Temperature: "+str(lat_long_val))
    return fig

@st.cache
def monthly_mean_calc(temperature_monthly_df,lat_long_list):
    #monthly mean calculation
    temperature_monthly_df = temperature_monthly_df.groupby('lat_long')
    date_split_df = df_date_split(temperature_monthly_df,lat_long_list)
    monthly_avg_temp = date_split_df.groupby(['lat_long','Year','Month'])[['daily_avg']].mean()
    monthly_avg_temp.rename(columns = {'daily_avg':'Monthly mean temperature'},inplace = True)
    return monthly_avg_temp


@st.cache(ttl=24*60*60)
def selecting_mean(monthly_avg_temp,option_mean,start_year,end_year):
    monthly_avg_temp = monthly_avg_temp.reset_index().set_index('Year').groupby('lat_long')
    grouped_monthly_mean = monthly_avg_temp.get_group(option_mean)
    df = grouped_monthly_mean.loc[start_year:end_year]
    df = df.reset_index()
    return df


def plot_mean_data(df,lat_long_val):
    title_text = "Monthly Mean Temperature: "+str(lat_long_val)
    highlight = alt.selection(
    type='single', on='mouseover', fields=['Year'], nearest=True)
    base = alt.Chart(df,title = title_text).encode(
    x = alt.X('Month:Q',scale = alt.Scale(domain=[1,12]),axis=alt.Axis(tickMinStep=1)),
    y = alt.Y('Monthly mean temperature:Q',scale = alt.Scale(domain =[int(df['Monthly mean temperature'].min()),int(df['Monthly mean temperature'].max())])),
    color = alt.Color('Year:O',scale = alt.Scale(scheme = 'magma'))
    )
    points = base.mark_circle().encode(
    opacity=alt.value(0),
    tooltip=[
        alt.Tooltip('Year:O', title='Year'),
        alt.Tooltip('Month:Q', title='Month'),
        alt.Tooltip('Monthly mean temperature:Q', title='Mean temp')
    ]).add_selection(highlight)

    lines = base.mark_line().encode(
    size=alt.condition(~highlight, alt.value(1), alt.value(3)))

    mean_chart = (points + lines).properties(width=1000, height=450).interactive()
    return mean_chart

def max_temp_plot(df_max,lat_long_val):
    fig_max = px.line(df_max,x = 'Year',y='Yearly_maximum_temp')
    fig_max.update_traces(line_color = 'maroon')
    fig_max.update_layout(
    yaxis = dict(tickfont = dict(size=15)),
    xaxis = dict(tickfont = dict(size=15)),
    plot_bgcolor = 'rgba(0,0,0,0)')
    fig_max.update_xaxes(gridcolor='whitesmoke')
    fig_max.update_yaxes(gridcolor = 'whitesmoke')
    fig_max.update_yaxes(title = "Annual Maximum Temperature (C)")
    # fig_max.update_layout(title = "Yearly Maximum Temperature: "+str(lat_long_val))

    return fig_max


def min_temp_plot(df_min,lat_long_val):
    fig_min = px.line(df_min, x= 'Year',y = 'Yearly_minimum_temp')
    fig_min.update_traces(line_color ='blue')
    fig_min.update_layout(
    yaxis = dict(tickfont = dict(size=15)),
    xaxis = dict(tickfont = dict(size=15)),
    plot_bgcolor = 'rgba(0,0,0,0)')
    fig_min.update_xaxes(gridcolor='whitesmoke')
    fig_min.update_yaxes(gridcolor = 'whitesmoke')
    fig_min.update_yaxes(title = "Annual Minimum Temperature (C)")
    # fig_min.update_layout(title = "Yearly Minimum Temperature: "+str(lat_long_val))

    return fig_min


#code for downloading Data as a CSV File
@st.cache
def convert_df(df):
     return df.to_csv().encode('utf-8')

# a = st.sidebar.empty()

#result dataframe contains the daily average value as well.
#Function for creating folium map and returning the latitude and Longitude of the clicked location
def map_creation(lat,long,clicked_lat,clicked_long):
    with st.sidebar:
        m = folium.Map(location = [9.14,40],zoom_start =7)
        fig.add_child(m)
        tile = folium.TileLayer(
        tiles = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
        attr = 'Esri',
        name = 'Esri Satellite',
        overlay = False,
        control = True).add_to(m)
        folium.TileLayer('Stamen Terrain').add_to(m)
        folium.TileLayer('Stamen Water Color').add_to(m)
        folium.LayerControl().add_to(m)
        if (clicked_lat == 0) and (clicked_long == 0):
            folium.Marker([lat,long]).add_to(m)
        else:
            folium.Marker([lat,long]).add_to(m)
            folium.Marker([clicked_lat,clicked_long]).add_to(m)
        st_data = st_folium(m,key = 'map_fig_1')
        return st_data

#df is the initial df that contains only et data
def search_func(latitude,longitude,lt_lng_lst,df):
    df['lat_radian'],df['long_radian'] = np.radians(df['lat']),np.radians(df['long'])
    df['dLON'] = df['long_radian'] - math.radians(longitude)
    df['dLAT'] = df['lat_radian'] - math.radians(latitude)
    df['distance'] = 6371 * 2 * np.arcsin(np.sqrt(np.sin(df['dLAT']/2)**2 + math.cos(math.radians(longitude)) * np.cos(df['lat_radian']) * np.sin(df['dLON']/2)**2))
    a = df['distance'].idxmin()
    nearest_neighbor = df._get_value(a,'lat_long')
    nearest_neighbor = lat_long_type(nearest_neighbor)
        # st.write("**Nearest Latitude and Longitude is :**",nearest_neighbor)
    return nearest_neighbor