I have some CSV which I want to see as a dashboard, so I can easily explore the data. - Create a dropzone where a user can drop his csv. Once drop, render a table + Interactive charts showing transaction trends, project type distributions, and geographic breakdowns transaction_id,date,project_type,project_id,seller,buyer,quantity,price_per_ton,total_value,standard,vintage_year,location TR-12493,2024-01-15,Reforestation,PRJ-4587,Carbon Forest Partners,GreenInvest Group,5000,12.50,62500.00,Gold Standard,2023,Brazil TR-12494,2024-01-17,Renewable Energy,PRJ-2839,SunPower Solutions,Eco Capital Fund,3200,9.75,31200.00,VCS,2023,India TR-12495,2024-01-21,Methane Capture,PRJ-6721,AgriTech Emissions,Climate Forward,2800,14.25,39900.00,CAR,2023,United States
To upload files, please first save the app
import streamlit as st
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from datetime import datetime
import io
st.set_page_config(layout="wide", page_title="Carbon Credits Dashboard")
st.title("Carbon Credits Dashboard")
st.markdown("Drop your CSV file below to visualize carbon credit transaction data.")
# CSS to improve the appearance of the file uploader
st.markdown("""
<style>
.uploadedFile {
border: 2px dashed #1f77b4;
border-radius: 10px;
padding: 30px;
text-align: center;
margin-bottom: 20px;
}
.stAlert {
background-color: #f0f8ff;
}
</style>
""", unsafe_allow_html=True)
# Sample data for display when no file is uploaded
sample_data = pd.DataFrame({
'transaction_id': ['TR-12493', 'TR-12494', 'TR-12495'],
'date': ['2024-01-15', '2024-01-17', '2024-01-21'],
'project_type': ['Reforestation', 'Renewable Energy', 'Methane Capture'],
'project_id': ['PRJ-4587', 'PRJ-2839', 'PRJ-6721'],
'seller': ['Carbon Forest Partners', 'SunPower Solutions', 'AgriTech Emissions'],
'buyer': ['GreenInvest Group', 'Eco Capital Fund', 'Climate Forward'],
'quantity': [5000, 3200, 2800],
'price_per_ton': [12.50, 9.75, 14.25],
'total_value': [62500.00, 31200.00, 39900.00],
'standard': ['Gold Standard', 'VCS', 'CAR'],
'vintage_year': [2023, 2023, 2023],
'location': ['Brazil', 'India', 'United States']
})
# File uploader
uploaded_file = st.file_uploader("Upload your CSV file", type=['csv'],
help="Upload a CSV file with carbon credit transaction data")
# Initialize df with sample data
df = sample_data
# If a file is uploaded, read it
if uploaded_file is not None:
try:
# Read the file
df = pd.read_csv(uploaded_file)
st.success("File successfully uploaded and processed!")
# Convert date to datetime
df['date'] = pd.to_datetime(df['date'])
# Sort by date
df = df.sort_values('date')
except Exception as e:
st.error(f"Error: {e}")
st.info("Using sample data instead.")
# If we're using sample data and not a real upload
elif uploaded_file is None:
st.info("No file uploaded. Displaying sample data for preview.")
# Convert date to datetime for sample data too
df['date'] = pd.to_datetime(df['date'])
df = df.sort_values('date')
# Dashboard content
def create_dashboard(data):
# Data overview section
st.header("Data Overview")
st.write(f"Total Transactions: {len(data)}")
# Create tabs for different views
tabs = st.tabs(["Transactions Table", "Trends Analysis", "Project Breakdown", "Geographic Distribution"])
# Transactions Table tab
with tabs[0]:
st.subheader("Transactions Table")
# Filters for the table
col1, col2, col3 = st.columns(3)
with col1:
project_types = ['All'] + sorted(data['project_type'].unique().tolist())
selected_project_type = st.selectbox("Filter by Project Type", project_types)
with col2:
standards = ['All'] + sorted(data['standard'].unique().tolist())
selected_standard = st.selectbox("Filter by Standard", standards)
with col3:
locations = ['All'] + sorted(data['location'].unique().tolist())
selected_location = st.selectbox("Filter by Location", locations)
# Apply filters
filtered_data = data.copy()
if selected_project_type != 'All':
filtered_data = filtered_data[filtered_data['project_type'] == selected_project_type]
if selected_standard != 'All':
filtered_data = filtered_data[filtered_data['standard'] == selected_standard]
if selected_location != 'All':
filtered_data = filtered_data[filtered_data['location'] == selected_location]
# Display table
st.dataframe(filtered_data, use_container_width=True)
# Export filtered data
if st.button("Export Filtered Data as CSV"):
csv = filtered_data.to_csv(index=False)
st.download_button(
label="Download CSV",
data=csv,
file_name="carbon_credits_filtered.csv",
mime="text/csv",
)
# Trends Analysis tab
with tabs[1]:
st.subheader("Transaction Trends")
# Time period selector
time_periods = ["Daily", "Weekly", "Monthly", "Quarterly", "Yearly"]
selected_period = st.selectbox("Select Time Period", time_periods)
# Prepare time-based data
if selected_period == "Daily":
df_time = data.copy()
df_time['period'] = df_time['date']
elif selected_period == "Weekly":
df_time = data.copy()
df_time['period'] = df_time['date'].dt.isocalendar().week.astype(str) + '-' + df_time['date'].dt.year.astype(str)
elif selected_period == "Monthly":
df_time = data.copy()
df_time['period'] = df_time['date'].dt.strftime('%Y-%m')
elif selected_period == "Quarterly":
df_time = data.copy()
df_time['period'] = 'Q' + (df_time['date'].dt.month // 3 + 1).astype(str) + '-' + df_time['date'].dt.year.astype(str)
else: # Yearly
df_time = data.copy()
df_time['period'] = df_time['date'].dt.year
# Aggregate data by time period
time_agg = df_time.groupby('period').agg({
'transaction_id': 'count',
'quantity': 'sum',
'total_value': 'sum'
}).reset_index()
# Create metrics
col1, col2, col3 = st.columns(3)
with col1:
st.metric("Total Transactions", f"{time_agg['transaction_id'].sum():,}")
with col2:
st.metric("Total Quantity (tons)", f"{time_agg['quantity'].sum():,}")
with col3:
st.metric("Total Value ($)", f"${time_agg['total_value'].sum():,.2f}")
# Create visualizations
# Transaction volume over time
fig1 = px.line(time_agg, x='period', y='transaction_id',
title=f"Transaction Count by {selected_period} Period",
labels={'period': 'Time Period', 'transaction_id': 'Number of Transactions'})
st.plotly_chart(fig1, use_container_width=True)
# Create two columns for the charts
col1, col2 = st.columns(2)
# Quantity over time
with col1:
fig2 = px.bar(time_agg, x='period', y='quantity',
title=f"Carbon Credits Quantity by {selected_period} Period",
labels={'period': 'Time Period', 'quantity': 'Quantity (tons)'})
st.plotly_chart(fig2, use_container_width=True)
# Value over time
with col2:
fig3 = px.bar(time_agg, x='period', y='total_value',
title=f"Transaction Value by {selected_period} Period",
labels={'period': 'Time Period', 'total_value': 'Value ($)'})
st.plotly_chart(fig3, use_container_width=True)
# Price trends
price_trends = data.groupby(data['date'].dt.to_period('M').astype(str)).agg({
'price_per_ton': 'mean'
}).reset_index()
fig4 = px.line(price_trends, x='date', y='price_per_ton',
title="Average Price per Ton Over Time",
labels={'date': 'Month', 'price_per_ton': 'Avg Price per Ton ($)'})
st.plotly_chart(fig4, use_container_width=True)
# Project Breakdown tab
with tabs[2]:
st.subheader("Project Type Analysis")
# Create project type breakdown
project_agg = data.groupby('project_type').agg({
'transaction_id': 'count',
'quantity': 'sum',
'total_value': 'sum'
}).reset_index()
# Create two columns for the charts
col1, col2 = st.columns(2)
# Project type by transaction count
with col1:
fig5 = px.pie(project_agg, values='transaction_id', names='project_type',
title="Transactions by Project Type",
hole=0.4)
st.plotly_chart(fig5, use_container_width=True)
# Project type by quantity
with col2:
fig6 = px.pie(project_agg, values='quantity', names='project_type',
title="Carbon Credit Quantity by Project Type",
hole=0.4)
st.plotly_chart(fig6, use_container_width=True)
# Project type and standard relationship
standard_project = data.groupby(['standard', 'project_type']).agg({
'quantity': 'sum'
}).reset_index()
fig7 = px.sunburst(standard_project, path=['standard', 'project_type'], values='quantity',
title="Standards and Project Types Relationship")
st.plotly_chart(fig7, use_container_width=True)
# Price comparison by project type
fig8 = px.box(data, x='project_type', y='price_per_ton',
title="Price Distribution by Project Type",
labels={'project_type': 'Project Type', 'price_per_ton': 'Price per Ton ($)'})
st.plotly_chart(fig8, use_container_width=True)
# Vintage year analysis
vintage_project = data.groupby(['vintage_year', 'project_type']).agg({
'quantity': 'sum'
}).reset_index()
fig9 = px.bar(vintage_project, x='vintage_year', y='quantity', color='project_type',
title="Carbon Credits by Vintage Year and Project Type",
labels={'vintage_year': 'Vintage Year', 'quantity': 'Quantity (tons)', 'project_type': 'Project Type'})
st.plotly_chart(fig9, use_container_width=True)
# Geographic Distribution tab
with tabs[3]:
st.subheader("Geographic Analysis")
# Geographic breakdown
geo_agg = data.groupby('location').agg({
'transaction_id': 'count',
'quantity': 'sum',
'total_value': 'sum',
'price_per_ton': 'mean'
}).reset_index()
# Create map visualization
fig10 = px.scatter_geo(geo_agg, locations='location', locationmode='country names',
size='quantity', color='price_per_ton',
hover_name='location',
hover_data=['transaction_id', 'quantity', 'total_value', 'price_per_ton'],
title="Carbon Credit Transactions by Location",
projection='natural earth',
color_continuous_scale=px.colors.sequential.Viridis)
st.plotly_chart(fig10, use_container_width=True)
# Geographic bar charts
col1, col2 = st.columns(2)
# Transactions by location
with col1:
fig11 = px.bar(geo_agg.sort_values('transaction_id', ascending=False),
x='location', y='transaction_id',
title="Transaction Count by Location",
labels={'location': 'Country', 'transaction_id': 'Number of Transactions'})
st.plotly_chart(fig11, use_container_width=True)
# Quantity by location
with col2:
fig12 = px.bar(geo_agg.sort_values('quantity', ascending=False),
x='location', y='quantity',
title="Carbon Credit Quantity by Location",
labels={'location': 'Country', 'quantity': 'Quantity (tons)'})
st.plotly_chart(fig12, use_container_width=True)
# Average price by location
fig13 = px.bar(geo_agg.sort_values('price_per_ton', ascending=False),
x='location', y='price_per_ton',
title="Average Price per Ton by Location",
labels={'location': 'Country', 'price_per_ton': 'Avg Price per Ton ($)'})
st.plotly_chart(fig13, use_container_width=True)
# Project types by location
location_project = data.groupby(['location', 'project_type']).agg({
'quantity': 'sum'
}).reset_index()
fig14 = px.treemap(location_project, path=['location', 'project_type'], values='quantity',
title="Project Types by Location")
st.plotly_chart(fig14, use_container_width=True)
# Create the dashboard with the data
create_dashboard(df)
# Footer
st.markdown("---")
st.markdown("### About this Dashboard")
st.markdown("""
This dashboard visualizes carbon credit transaction data. Upload your own CSV file with the required columns to analyze your data.
Required columns:
- transaction_id: Unique identifier for each transaction
- date: Transaction date
- project_type: Type of carbon credit project
- project_id: Unique identifier for each project
- seller: Organization selling the credits
- buyer: Organization buying the credits
- quantity: Amount of carbon credits in tons
- price_per_ton: Price per ton of carbon credits
- total_value: Total transaction value
- standard: Certification standard
- vintage_year: Year the credits were generated
- location: Country where the project is located
""")
Hi! I can help you with any questions about Streamlit and Python. What would you like to know?