Ver código
views.py Code
def weather_phenomena(request):
search_line = "def weather_phenomena(request):"
pattern = "# end_gridspec"
content_json = "/static/json/data-science/content.json"
project_key = "weather_phenomena"
template_path = "portfolio/templates/data-science/data-visualization/index.html"
# Path to import files
file_path = os.path.join(static_dir, 'datasets/weather_phenomena/climate_data.csv')
file_path2 = os.path.join(static_dir, 'datasets/weather_phenomena/province_detail.csv')
file_path3 = os.path.join(static_dir, 'datasets/weather_phenomena/station_detail.csv')
answer = [] # Initialize list to store results
try:
# Call the get_views_code to retrieve code in the views file
views_code = get_views_code(search_line, pattern, module_dir)
content_json_data = get_content_json_data(content_json, project_key)
template_code = get_template_code(template_path)
# The weather sample is static; the two figures (~5 s to draw) are cached for
# 15 minutes, like the KNN and census demos.
cached = cache.get("subplots_demo:results")
if cached is not None:
context = {'views': views_code, 'content': content_json_data, 'template': template_code, **cached}
return render(request, 'data-science/data-visualization/subplots.html', context)
df_climate = pd.read_csv(file_path)
df_province = pd.read_csv(file_path2)
df_station = pd.read_csv(file_path3)
filter_condition_id_province = 1
filtered_df_station = df_station[df_station['province_id'] == filter_condition_id_province]
# Merge filtered_df_station with df_climate
merged_df = pd.merge(filtered_df_station, df_climate, on='station_id', how='inner')
# Merge the result with df_province
df = pd.merge(merged_df, df_province, left_on='province_id', right_on='province_id', how='inner')
df.dropna(subset=['Tn', 'Tx', 'Tavg'], how='any', inplace=True)
unique_station_id = df['station_id'].unique()
data_to_html = th_scope(df.head(400).to_html(classes='table table-bordered table-striped to_html', index=True))
# Calculate the number of rows and columns for the grid
num_rows = (len(unique_station_id) + 1) // 2 # Add 1 and use integer division to round up
num_cols = 2
fig, axes = plt.subplots(num_rows, num_cols, figsize=(12, 8), sharex=True, sharey=True)
for idx, station_id in enumerate(unique_station_id):
row = idx // 2
col = idx % 2
ax = axes[row, col]
# Generate a plot for the station_id
data_for_station = df[df['station_id'] == station_id]
# Replace 'x_values' and 'y_values' with your specific data for plotting
station_name = data_for_station['station_name'].iloc[0] # Get the station_name for the current station
x_values = pd.to_datetime(data_for_station['date'], format='%d-%m-%Y') # Convert 'date' to datetime
y_values = data_for_station['RR'] # Replace with the actual column you want to plot
# Create a secondary y-axis for 'RH_avg'
ax2 = ax.twinx()
y_values_rh = data_for_station['RH_avg'] # Replace with the actual 'RH_avg' column
ax.plot(x_values, y_values, color='blue', label='Rain Fall mm')
ax2.fill_between(x_values, y_values_rh, color='gray', label='RH_avg', alpha=0.5)
ax.set_title(f'Station Name {station_name}')
ax.set_ylabel('Rain Fall mm', color='blue')
ax2.set_ylabel('RH_avg', color='red')
# Adjust layout to prevent overlapping titles
plt.tight_layout()
# Save the plot to a BytesIO object
graphic = decode_graph(plt)
# Create subplots for each station_id
fig, axes = plt.subplots(num_rows, num_cols, figsize=(15, 15), sharex=True, sharey=True)
# Create empty lists to store legend handles and labels
legend_handles = []
legend_labels = []
# Iterate through unique_station_id
for idx, station_id in enumerate(unique_station_id):
row = idx // 2
col = idx % 2
ax = axes[row, col]
# Generate a plot for the station_id
data_for_station = df[df['station_id'] == station_id]
data_for_station['date'] = pd.to_datetime(data_for_station['date'], format='%d-%m-%Y')
station_name = data_for_station['station_name'].iloc[0] # Get the station_name for the current station
# Calculate the minimum and maximum average temperature for each month
monthly_min_temp = data_for_station.groupby(data_for_station['date'].dt.to_period('M'))['Tn'].min()
monthly_max_temp = data_for_station.groupby(data_for_station['date'].dt.to_period('M'))['Tx'].max()
monthly_avg_temp = data_for_station.groupby(data_for_station['date'].dt.to_period('M'))['Tavg'].mean()
# Create a DataFrame for monthly temperature values
monthly_temp_df = pd.DataFrame(
{'Month': monthly_min_temp.index.to_timestamp(), 'Min Temp (°C)': monthly_min_temp.values,
'Max Temp (°C)': monthly_max_temp.values, 'Avg Temp (°C)': monthly_avg_temp.values})
# Plot the minimum and maximum monthly average temperatures
ax.plot(monthly_temp_df['Month'], monthly_temp_df['Min Temp (°C)'], label='Min Temp (°C)', marker='o',
color='blue')
ax.plot(monthly_temp_df['Month'], monthly_temp_df['Max Temp (°C)'], label='Max Temp (°C)', marker='o',
color='red')
ax.set_title(f'Station Name {station_name}')
ax.set_ylabel('Temperature (°C)')
ax.legend()
# Add a trendline for Avg Temp (°C)
ax2 = ax.twinx()
x_values = np.arange(len(monthly_temp_df['Month']))
y_values = monthly_temp_df['Avg Temp (°C)']
trendline = np.polyfit(x_values, y_values, 1)
ax2.plot(monthly_temp_df['Month'], np.polyval(trendline, x_values), label='Trendline (Avg Temp)',
linestyle=':', color='orange')
# Add the legend for trendline once
legend_handles.append(ax2.lines[0])
legend_labels.append('Trendline (Avg Temp)')
# Adjust legend positions
for ax in axes.flat:
lines1, labels1 = ax.get_legend_handles_labels()
ax.legend(lines1 + legend_handles, labels1 + legend_labels, loc='upper left')
# Set common x-label and rotate x-axis labels for readability
plt.xlabel('Month')
# Adjust layout to prevent overlapping titles
plt.tight_layout()
# Save the plot to a BytesIO object
graphic2 = decode_graph(plt)
computed = {'answer': answer, 'data_to_html': data_to_html, 'graphic': graphic, 'graphic2': graphic2}
cache.set("subplots_demo:results", computed, 60 * 15)
context = {'views': views_code, 'content': content_json_data, 'template': template_code, **computed}
return render(request, 'data-science/data-visualization/subplots.html', context)
except FileNotFoundError:
context = {'description': 'File not found. Please check the file path or create the file if it does not',
'reference': "Read & Process Excel files with Data Frame"}
return render(request, 'data-science/retrieve_error.html', context)
except TemplateDoesNotExist:
context = {'description': 'Template not found. Please check the file path or create the file if it does not',
'reference': "Books Store connection from XML File"}
return render(request, 'data-science/retrieve_error.html', context)
else:
context = {'description': 'Something is wrong to retrieve data.',
'reference': "Something wrong with retrieving Data with Pandas"}
return render(request, 'data-science/retrieve_error.html', context)
Template
{% extends 'base.html' %}
{% load i18n %}
{% load static %}
{% load cached_pygments %}
{% block title %}{% trans "Daily Climate Charts (matplotlib)" %} | Marco A. Parra F.{% endblock %}
{% block meta_description %}{% trans "Daily climate series plotted with matplotlib and served as inline images from a Django view." %}{% endblock %}
{% block content %}
<br>
<br>
<section class="container-section mb-4">
<div class="container-fluid">
<div class="row g-0">
<div class="portfolio-box-caption">
<div class="card">
{% for key, values in content.items %}
{% for items in content.values %}
{% for value in items %}
<h2 class="cart-title text-center">{{ value.title }}</h2>
<hr>
<div class="card-body mb-3">
<h5 class="card-subtitle mb-3">{{ value.description }}</h5>
<p class="card-text">{{ value.key_components }}</p>
</div>
</div>
</div>
</div>
<hr>
</div>
</section>
<section class="container-section mb-4">
<div class="container-fluid">
<h1>Step By Step data processing</h1>
<hr>
<div class="row g-0 mb-3 ">
<div class="portfolio-box-caption">
<h3>Data Collections</h3>
<div class="row">
<p>{{ value.data_collection }}</p>
<em>
To retrieve data from datasets using pandas and convert it into a DataFrame, using the pd.read_csv() used to read the data source format.<br>
</em>
</div>
<div class="row container-app" style="width: 100%; max-height: 50rem; /* Set the desired height here */
overflow-y: scroll; /* Enable vertical scrolling */">
<pre>
<code class="python">
file_path = parent_directory + '/mparraf/static/datasets/agrometeorologia-chillan2013-2023.csv'
df = pd.read_csv(file_path, skiprows=5, header=0)
</code>
</pre>
</div>
</div>
</div>
<hr>
<div class="row g-0 mb-3">
<div class="portfolio-box-caption">
<h3>Data Preparation, and Exploration</h3>
<div class="row">
<p>{{ value.data_preparation_exploration }}</p>
</div>
<div class="row container-app">
<pre>
<code>
date_columns = ['Tiempo UTC-4']
integer_columns = ['Temperatura del Aire Mínima ºC', 'Temperatura del Aire Máxima ºC']
df_cleaned = df.dropna(subset=date_columns, how='all').reset_index(drop=True)
df_cleaned = df_cleaned.dropna(subset=integer_columns, how='all')
df_cleaned.rename(columns={integer_columns[0]:'TMIN', integer_columns[1]:'TMAX'}, inplace=True)
</code>
</pre>
</div>
<hr>
<div class="row container-app" style="width: 100%; max-height: 50rem; /* Set the desired height here */
overflow-y: scroll; /* Enable vertical scrolling */">
{{ merge_university_town|safe }}
</div>
</div>
</div>
<hr>
<div class="row g-0 mb-3">
<div class="portfolio-box-caption">
<h3>Enhancing Data Insights: Leveraging Matplotlib for Interactive Visualizations in Your Django Project</h3>
<div class="row">
<p>
{{ value.data_visualization }}
</p>
<em>In the virtual environment is necessary install the matplolib library and realize the importation in the views.py</em>
</div>
<div class="row container-app">
<pre>
<code>
import matplotlib.pyplot as plt
plt.figure(figsize=(16, 10))
plt.title('Record high and record low temperatures by day (period 2010-2023)', alpha=0.8)
plt.plot(df_cleaned['TMAX'], c='red', label='Record High')
plt.plot(df_cleaned['TMIN'], c='blue', label='Record Low')
plt.gca().fill_between(range(len(df_cleaned)), df_cleaned['TMAX'], df_cleaned['TMIN'], facecolor='black',
alpha=0.25)
plt.legend(['Record High T°', 'Record Low T°'])
plt.xlabel('Days')
plt.ylabel('Temperature, (tenths C°)')
for spine in plt.gca().spines.values():
spine.set_visible(False)
# Save the plot to a BytesIO object
graphic = decode_graph(plt)
</code>
</pre>
</div>
<div class="row container-app" style="width: 100%; max-height: 50rem; /* Set the desired height here */
overflow-y: scroll; /* Enable vertical scrolling */">
<img src="data:image/png;base64,{{ plot }}" alt="Temperatures Plot graph">
</div>
</div>
</div>
<hr>
<div class="row g-0 mb-3">
<div class="portfolio-box-caption">
<h3>Dynamically Generating and Serving Graphs in Your Django Application (Plot graph)</h3>
<div class="row">
<p>
To generate a plot a function was created to save it in the 'BytesIO' buffer, convert it to a base64-encoded string, and then use this string to display the graph on a web page or include it in a downloadable report. This allows you to generate and serve graphs within your Django application dynamically.
</p>
</div>
<div class="row container-app">
<pre>
<code>
from io import BytesIO
import base64
def decode_graph(plt):
# Save the plot to a BytesIO object
buffer = BytesIO()
plt.savefig(buffer, format='png')
buffer.seek(0)
image_png = buffer.getvalue()
buffer.close()
# Encode the image to base64
graphic = base64.b64encode(image_png).decode()
return graphic
</code>
</pre>
</div>
</div>
</div>
<hr>
<div class="row g-0 mb-3">
<div class="portfolio-box-caption">
<h3>Chillán Climate Analysis: Unveiling Temperature Trends Through Data Visualization</h3>
<div class="row">
<h6>Data Preparation</h6>
<p>
Highlighting Anomalies: Overlay a scatter plot with data from the year 2022. This scatter plot will emphasize any data points (representing temperature highs and lows) where the records set between 2010 and 2023 were surpassed in 2022. These points will provide valuable insights into notable climate anomalies.
</p>
</div>
<div class="row container-app">
<pre>
<code>
df_cleaned['Tiempo UTC-4'] = pd.to_datetime(df_cleaned['Tiempo UTC-4'], format='%d-%m-%Y')
df_2022 = df_cleaned[df_cleaned['Tiempo UTC-4'].dt.year == 2022]
max_tmax_2022 = df_2022['TMAX'].max()
min_tmax_2022 = df_2022['TMIN'].min()
</code>
</pre>
</div>
</div>
</div>
<hr>
<div class="row g-0 mb-3">
<div class="portfolio-box-caption">
<h3>Dynamically Generating and Serving Graphs in Your Django Application (Scatter graph)</h3>
<div class="row container-app">
<pre>
<code>
plt.figure(figsize=(16, 10))
plt.title('Record high and record low temperatures by day (year 2022)', alpha=0.8)
plt.scatter(df_cleaned['Tiempo UTC-4'], df_cleaned['TMAX'], c='red', label='Record High')
plt.scatter(df_cleaned['Tiempo UTC-4'], df_cleaned['TMIN'], c='blue', label='Record Low')
plt.legend(['Record High T (2015)°', 'Record Low T° (2015)', 'Record High (period 2005-2014)',
'Record Low (period 2005-2014)'])
plt.xlabel('Date')
plt.ylabel('Temperature, (tenths C°)')
for spine in plt.gca().spines.values():
spine.set_visible(False)
x = plt.gca().xaxis
for item in x.get_ticklabels():
item.set_rotation(45)
xlim_start = pd.to_datetime('01-01-2010', format='%d-%m-%Y')
xlim_end = pd.to_datetime('01-10-2023', format='%d-%m-%Y')
plt.xlim([xlim_start, xlim_end])
plt.axhline(y=max_tmax_2022, color='r', linestyle='-', label='Record High (period 2010-2023)')
plt.axhline(y=min_tmax_2022, color='b', linestyle='-', label='Record Low (period 2010-2023)')
graphic2 = decode_graph(plt)
</code>
</pre>
</div>
<div class="row container-app" style="width: 100%; max-height: 50rem; /* Set the desired height here */
overflow-y: scroll; /* Enable vertical scrolling */">
<img src="data:image/png;base64,{{ scatter }}" alt="Temperatures Scatter graph">
</div>
</div>
</div>
<hr>
{% endfor %}
{% endfor %}
{% endfor %}
<hr>
</div>
</section>
<section class="container-section mb-4">
<div class="container-fluid">
<div class="row g-0">
<div class="portfolio-box-caption">
<div class="row">
<div class="col-12 col-sm-10">
<h3 class="portfolio-box-headers" style="text-align:center">
{% trans "Show Code" %}</h3>
</div>
<div class="col">
<button type="button" class="btn btn-light" onclick="$('#section-w').toggle();">
Show/Hide
</button>
</div>
</div>
</div>
<hr>
<div class="container" style="display:none;" id="section-w">
<div class="row mb-4">
<div class="col">
<h4>views.py Code</h4>
<div class="sourcecode">
{% for item in views %}
{{ item|pygmentize:"python3" }}
{% endfor %}
</div>
</div>
<div class="col">
<h4>Template</h4>
<div class="sourcecode">
{{ template|pygmentize:"html" }}
</div>
</div>
</div>
</div>
</div>
</div>
</section>
{% endblock %}