Citibike Ain't Got Flow

Posted on Jul 25, 2016

Motivation: Many of my friends and family members regularly use citibike as an eco-friendly, active way of getting around New York City.  Though they enjoy the service, I often hear them complain that there are no bikes where they want them and too many bikes where they don't want them.  I sought to understand user patterns and bike distribution across the many citibike docks scattered throughout the city.

Data: Citibike has released downloadable trip histories for every month of their service since July of 2013.  I pulled the dataset for just last month (June, 2016), which contains the following (n = 1,460,318):

  • Trip Duration (seconds)
  • Start Time and Date
  • Stop Time and Date
  • Start Station Name
  • End Station Name
  • Station ID
  • Station Lat/Long
  • Bike ID
  • User Type (Customer = 24-hour pass or 7-day pass user; Subscriber = Annual Member)
  • Gender (Zero=unknown; 1=male; 2=female)
  • Year of Birth

Analysis and Visualization

First I wanted to understand general citibike usage by time of day.  To do this, I decided to count the total number of citibike trips started for each hour of the day and plot my results on a bar chart.  (initial data manipulation code at the end of the post)

Screen Shot 2016-07-24 at 9.36.19 PM

One can see that citibike is very clearly a commuter tool, as the bar chart peaks during morning and evening rush hours.

Because citibike usage is highest during rush hours, it seemed important to distinguish weekday and weekend usage.  Separating all trips by weekday starts and weekend starts and plotting hourly usage on a bar chart gave the following two graphs.

Screen Shot 2016-07-24 at 9.40.50 PM

Screen Shot 2016-07-24 at 9.42.23 PM


Not surprisingly, user patterns are very different on weekdays and weekends.  Interested in potential directional flow problems caused by commuters using citibike, I decided to proceed with just weekday data.

City Usage Visualization Functions

In order to visualize activity at individual stations as well as across the city as a whole, I wrote two functions to generate maps of station usage across specified time periods.

maps_percent(x, y): creates a map that shows, between hours x and y, the percentage of all citibike trips that started at each station.  Each station is represented by a dot, and its percentage is represented by dot color and size.  maps_percent also prints the top 5 stations with the highest percentage, as well as the median percentage. (code at the end of the post)

maps_ratio(x, y): creates a map that shows, between hours x and y, the ratio of trips that started and trips that ended at each dock.  Each station is represented by a dot, and the positivity of its trips started:ended ratio is represented by dot color and size.  Maps_ratio also prints the top 5 stations with the highest ratio, as well as the median ratio. (code at the end of the post)


Mapping Station Activity

I first wanted to get a sense of station activity in general (not broken down by hour) to understand which stations experienced heavy (start) usage and which had extreme trips started:ended ratios.

According to this graph, more citibike trips start in commercial, downtown Manhattan than in residential neighborhoods such as the Upper East and West Sides, alphabet city, and Brooklyn.


According to this graph, most stations generally have similar flow ratios of around 1 trip started for every trip ended. However, there are several major outliers in both Manhattan and Brooklyn who see far more trips leave than arrive, and would thus naturally become depleted.














Mapping Station Activity by Time of Day

Then I wanted to see how this usage changed by time of day.  I chose hour groupings that represented morning rush hour, the work day, and evening rush hour.  Particularly interested in the flow and natural redistribution of bikes across individual stations, I chose the maps_ratio() function. (click to enlarge)

3 These three graphs show several interesting patterns.  In the morning (hrs 6-10), stations in midtown and the financial district (really most of the central island, through to the tip) have low start:end ratios, whereas peripheral, residential neighborhoods show high ratios.  Commuters take bikes into the center of Manhattan on their way to work, and there is little balancing traffic in the other direction.  This effect seems to disappear during the day (hrs 11-15) when there is a lot of parity between the flow ratios of different stations--the middle of a work day seems to create no clear usage directionality.  In the evening, the commuter effect reappears, except this time not surprisingly in the reverse.  Stations in midtown and the financial district have higher flow ratios than in peripheral residential neighborhoods as people commute home from work.  Additionally, large outliers (big black dots) appear during morning and even rush hours, and disappear during the day--which can be explained by the fact that many of them are located around transportation hubs.


  • There is a very clear difference between weekday and weekend citibike user patterns.
  • Differences across neighborhood:
    • midtown and central manhattan have high shares of all trips started, whereas alphabet city, Brooklyn, and the Upper East/West Sides have low shares of all trips started.
    • Ratio disequilibrium arises during commuter hours (large black dots appear on ratio plots during morning and evening rush hours), which means certain docks are naturally depleted during those times.  In the morning, there is flow out of residential neighborhoods into midtown and the downtown financial district.  In the evening, the opposite is true.
  • During the middle of the workday (hours 11-15), flow is naturally more equilibrated (dots are more similar in size and color to each other and outliers disappear).
  • Usage and ratio visualizations are dominated by very strong individual points--frequently transportation hubs.
    • Pershing Square North -- Grand Central Area (% of all trips graph)
    • Penn Station Valet (ratio plots 0-23 & 6-10)
    • W 42 St & Dyer Ave - Port Authority/Lincoln Tunnel Area (ratio plots 0-23 & 6-10)
    • W 52 St & 5 Ave - Rockefeller Center Area (ratio plot 16-20)

Further Questions:

  • Where is the unmet demand?  Though there is clearly usage disequilibrium at certain stations, that might be due partly to manual redistribution (trucks shuttling bikes to and from certain stations) to seemingly high start-traffic stations.  Redistribution of this sort makes those stations' trips_started:trips_ended ratios even more lopsided, as truck refills allow a station additional starts without corresponding additional ends.  What other stations could achieve such lopsided ratios if manually refilled?
  • What would a similar analysis look like for weekend data?
  • How do user patterns change by time of year?

With More Time:

  • Citibike only gets marginal revenue from non-subscriber usage (subscribers pay an annual fee).  Many non-subscribers are tourists, and thus likely do not conform to commuter patterns.  An analysis of non-subscriber usage patterns might provide insights more directly geared towards revenue maximization than usage maximization.


Initial Data Manipulation code:

maps_percent Function Code:

maps_ratio Function Code:

Map templates from URL :
Information from URL :



About Author

William Bartlett

Will Bartlett is a History of Science and Medicine Major from Yale University who recently took a leave of absence from medical school to explore data science. As an undergraduate, he studied the role of data in medicine...
View all posts by William Bartlett >

Leave a Comment

No comments found.

View Posts by Categories

Our Recent Popular Posts

View Posts by Tags

#python #trainwithnycdsa 2019 2020 Revenue 3-points agriculture air quality airbnb airline alcohol Alex Baransky algorithm alumni Alumni Interview Alumni Reviews Alumni Spotlight alumni story Alumnus ames dataset ames housing dataset apartment rent API Application artist aws bank loans beautiful soup Best Bootcamp Best Data Science 2019 Best Data Science Bootcamp Best Data Science Bootcamp 2020 Best Ranked Big Data Book Launch Book-Signing bootcamp Bootcamp Alumni Bootcamp Prep boston safety Bundles cake recipe California Cancer Research capstone car price Career Career Day citibike classic cars classpass clustering Coding Course Demo Course Report covid 19 credit credit card crime frequency crops D3.js data data analysis Data Analyst data analytics data for tripadvisor reviews data science Data Science Academy Data Science Bootcamp Data science jobs Data Science Reviews Data Scientist Data Scientist Jobs data visualization database Deep Learning Demo Day Discount disney dplyr drug data e-commerce economy employee employee burnout employer networking environment feature engineering Finance Financial Data Science fitness studio Flask flight delay gbm Get Hired ggplot2 googleVis H20 Hadoop hallmark holiday movie happiness healthcare frauds higgs boson Hiring hiring partner events Hiring Partners hotels housing housing data housing predictions housing price hy-vee Income Industry Experts Injuries Instructor Blog Instructor Interview insurance italki Job Job Placement Jobs Jon Krohn JP Morgan Chase Kaggle Kickstarter las vegas airport lasso regression Lead Data Scienctist Lead Data Scientist leaflet league linear regression Logistic Regression machine learning Maps market matplotlib Medical Research Meet the team meetup methal health miami beach movie music Napoli NBA netflix Networking neural network Neural networks New Courses NHL nlp NYC NYC Data Science nyc data science academy NYC Open Data nyc property NYCDSA NYCDSA Alumni Online Online Bootcamp Online Training Open Data painter pandas Part-time performance phoenix pollutants Portfolio Development precision measurement prediction Prework Programming public safety PwC python Python Data Analysis python machine learning python scrapy python web scraping python webscraping Python Workshop R R Data Analysis R language R Programming R Shiny r studio R Visualization R Workshop R-bloggers random forest Ranking recommendation recommendation system regression Remote remote data science bootcamp Scrapy scrapy visualization seaborn seafood type Selenium sentiment analysis sentiment classification Shiny Shiny Dashboard Spark Special Special Summer Sports statistics streaming Student Interview Student Showcase SVM Switchup Tableau teachers team team performance TensorFlow Testimonial tf-idf Top Data Science Bootcamp Top manufacturing companies Transfers tweets twitter videos visualization wallstreet wallstreetbets web scraping Weekend Course What to expect whiskey whiskeyadvocate wildfire word cloud word2vec XGBoost yelp youtube trending ZORI