Analyzing the Distribution and Competition Between Starbucks and Luckin Coffee Using Python Data Visualization
Using Python and the Shapely library, this article visualizes and compares the nationwide store distribution of Starbucks and Luckin Coffee, revealing that Starbucks concentrates in coastal first‑tier cities while Luckin is more dispersed, with an average of 0.6 Luckin stores within 500 m of each Starbucks location.
In this tutorial we use Python and the Shapely library to fetch, process, and visualize the 2022 nationwide store data of Starbucks and Luckin Coffee, comparing their quantity, regional distribution, and spatial relationship.
The datasets contain store name, latitude, longitude, and city, with a noted ~20% count error. Data are accessed via API calls, as shown in the first code snippet.
import requests<br/>headers = {"x-token": "你的鉴权token"}<br/>response = requests.get("http://app.chafer.nexadata.cn/openapi/v1/sheet/sht22nId5uouP2/records?size=1&page=1", headers=headers)<br/>print(response.json())After retrieving the data, we import necessary libraries and extract all pages of records for both brands.
# 导入相关库<br/>import pandas as pd<br/>import requests<br/>import time<br/>from shapely.geometry import Point<br/>from shapely.geometry.polygon import PolygonWe then define helper functions to create a 500 m radius circle around each Starbucks store, convert coordinates to points, and count how many Luckin stores fall inside each circle.
def circle(data, radius):<br/> center_latitude = float(data['维度'])<br/> center_longitude = float(data['经度'])<br/> center_point = Point(center_longitude, center_latitude)<br/> circle = center_point.buffer(radius/111300)<br/> polygon = Polygon(circle.exterior)<br/> return polygon<br/><br/>def point(data):<br/> center_latitude = float(data['维度'])<br/> center_longitude = float(data['经度'])<br/> return Point(center_longitude, center_latitude)<br/><br/>def is_inside(data):<br/> polygon = data['Polygon']<br/> n = 0<br/> luckin_city = luckin[luckin['城市']==data['城市']]<br/> for pt in luckin_city['Point']:<br/> if polygon.contains(pt):<br/> n += 1<br/> return nApplying these functions yields a new column Luckin_numbers indicating the count of Luckin stores within 500 m of each Starbucks location.
Key findings include:
On average, each Starbucks store is surrounded by 0.6 Luckin stores within 500 m.
The maximum number of Luckin stores near a single Starbucks is 7.
City‑level analysis shows Linyi has the highest average of 1.8 Luckin stores per Starbucks.
Visualizations (heat maps and top‑20 city bar charts) illustrate that Starbucks is concentrated in coastal first‑tier cities, while Luckin has a more dispersed presence, even in many third‑ and fourth‑tier inland cities.
The study demonstrates how simple Python scripts and geospatial libraries can uncover competitive spatial patterns between coffee chains, suggesting strategic insights for market expansion.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.