Visualizing Real-World Bike Rental Data with Python


I recently worked on a dataset tracking daily bike rentals over time — a perfect use case to test out how Python visualizations can turn raw time series into readable insights.
The project started with chaos: jagged lines, unreadable axes, and unclear stories. But with a few critical techniques — rolling averages, resampling, and Matplotlib’s hidden tricks — the data began to speak clearly.
Here’s a breakdown of how that happened.
The Dataset
The dataset included:
Daily rental counts
Timestamps
Weather conditions
It was messy enough to require real cleaning — and that made the learning deeper.
1) Turning That Chaos Into Clarity (Step by Step)
Here’s the exact process I followed to go from that mess to something readable:
Convert ‘Date’ column to datetime:
df['Date'] = pd.to_datetime(df['Date'])
Set it as index to enable resampling:
df.set_index('Date', inplace=True)
Handle missing values (if any):
df.dropna(inplace=True)
Smooth trends using a rolling average:
df['7D_Rolling'] = df['Rental Count'].rolling(window=7).mean()
Resample to monthly average:
monthly_avg = df['Rental Count'].resample('M').mean()
Polish with figure sizing + axis formatting:
import matplotlib.dates as mdates ax = df['7D_Rolling'].plot(figsize=(12, 6), label='7-day Rolling Avg') ax.xaxis.set_major_locator(mdates.MonthLocator()) ax.xaxis.set_major_formatter(mdates.DateFormatter('%b')) plt.legend()
2) Average Rentals by Weekday
Once the time series was clean, I got curious:
Do certain weekdays consistently get more rentals?
Hypothetical Problem:
The dataset had Date
as index but no Day
column. I couldn’t directly group by day names.
Fix:
I extracted day names from the datetime index:
df['Day'] = df.index.day_name()
weekday_avg = df.groupby('Day')['Rental Count'].mean().sort_values()
3) Finding the Most Popular Hours
Then I wanted to know:
At what time of day are rentals most frequent?
Hypothetical Problem:
The data had timestamps, but hours weren’t separate. Plotting directly would group by full datetime — unreadable.
Fix:
I extracted the hour from the timestamp:
df['Hour'] = df.index.hour
hourly_avg = df.groupby('Hour')['Rental Count'].mean()
Final Thoughts
This wasn’t just a visualization project — it was about designing clarity in the middle of chaos.
The raw data looked meaningless until I smoothed, grouped, and reframed it
Every tiny formatting step made the insight more obvious
And when I zoomed in by hour and out by month, the human behavior in the data started showing
No flashy dashboards. Just thoughtful plots that told real stories.
Subscribe to my newsletter
Read articles from Kartik Sharma directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
