One Scatter Plot, Four Insights: Color, Size & Log Scales
You just learned plt.plot(x, y) โ two variables, one line. Your boss now asks: "Show me spend vs revenue, but also which campaigns were most profitable and which reached the most customers โ in one chart for the deck." That is 4 variables and you have a 2D screen. This article shows how color, size, and log scales turn a plain scatter into a 4-dimensional story โ using a 5-row campaign table you can picture immediately.
1. The Data: 5 Campaigns, 4 Numbers Each
Same e-commerce context as the rest of the course โ each row is a marketing campaign:
| Campaign | Spend ($) | Revenue ($) | Profit Margin (%) | Customers Reached |
|---|---|---|---|---|
| Summer Sale | 10,000 | 42,000 | 18 | 8,200 |
| Influencer Push | 35,000 | 95,000 | 31 | 3,100 |
| Email Blast | 2,000 | 18,000 | 42 | 12,400 |
| TV Spot | 120,000 | 210,000 | 12 | 1,800 |
| Referral Bonus | 8,000 | 38,000 | 35 | 6,500 |
Plotting only x=spend, y=revenue hides that Email Blast (tiny spend, 42% margin, 12K customers) was the most efficient and TV Spot (huge spend, 12% margin) was wasteful. Let's encode the other two columns visually.
2. 4 Dimensions on a 2D Screen โ How Each Channel Maps
| Visual Channel | Data Column | Parameter | What the Viewer Sees |
|---|---|---|---|
| Horizontal position | Spend | x= | Left = cheap, Right = expensive |
| Vertical position | Revenue | y= | Bottom = low revenue, Top = high |
| Color | Profit Margin | c= + cmap='viridis' | Dark purple = thin margin, Yellow = fat margin (colorbar tells the scale) |
| Dot size | Customers Reached | s= | Small dot = niche, Big bubble = mass reach |
3. The Code โ Read It as "One Line Per Dimension"
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 6))
# x and y โ spend vs revenue
# c + cmap โ profit margin as color
# s โ customers as bubble size
# alpha โ transparency so overlapping bubbles stay readable
scatter = plt.scatter(
x=df['marketing_spend'],
y=df['revenue'],
c=df['profit_margin'], # 3rd dimension: color
cmap='viridis', # yellow = high margin, purple = low margin
s=df['customer_count'] / 10, # 4th dimension: bubble size (divide to fit screen)
alpha=0.65, # see-through so overlaps don't hide
edgecolors='w', linewidth=0.5
)
cbar = plt.colorbar(scatter)
cbar.set_label('Profit Margin (%)', fontsize=11)
plt.xlabel('Marketing Spend ($)', fontsize=12)
plt.ylabel('Revenue Generated ($)', fontsize=12)
plt.title('Campaign Performance: Spend vs Revenue & Profitability', fontsize=14, fontweight='bold')
plt.grid(True, linestyle='--', alpha=0.5)
plt.tight_layout()
plt.show()
Executive read: Email Blast is a small yellow bubble high up on the left โ low spend, high margin, big reach. TV Spot is a dark purple dot far right โ expensive, low margin, tiny reach. One chart, one decision: shift budget from TV to Email.
4. When Dots Pile Up: Log Scales
Some metrics span orders of magnitude โ YouTube views from 1,000 to 100,000,000, or revenue from $45 to $1.2M. On a linear axis, 90% of dots crush into the bottom-left corner and the trend disappears.
Fix: plt.xscale('log') or plt.yscale('log') โ each tick is ร10, so 1K, 10K, 100K, 1M get equal space. Hidden linear relationships suddenly appear along a diagonal.
# Before: plt.scatter(x=df['views'], y=df['revenue']) # dots crushed
plt.xscale('log') # spread the x-axis logarithmically
plt.yscale('log') # optionally both axes
plt.show()
When a prompt says "extreme magnitudes / power-law / bunching in corner" โ think log scale. This is Quiz 2 Q12.
5. Quick Tip: Long Labels โ Go Horizontal
Category names like "Home & Kitchen โ Small Appliances" overlap when tilted. Use plt.barh() (horizontal bars) instead of plt.bar() โ same data, labels stay readable. Seaborn equivalent: sns.barplot(..., orient='h').