0
# Coordinate Systems
1
2
Coordinate systems transform the positioning of geometric objects and control how data is mapped to the plot space. They enable specialized visualizations like flipped axes, fixed aspect ratios, polar coordinates, and transformed scales. Plotnine provides coordinate system functions that work seamlessly with all geometric objects and scales.
3
4
## Capabilities
5
6
### Basic Coordinate Systems
7
8
Fundamental coordinate transformations for standard and specialized plot layouts.
9
10
```python { .api }
11
def coord_cartesian(xlim=None, ylim=None, expand=True):
12
"""
13
Standard Cartesian coordinate system (default).
14
15
Linear mapping between data coordinates and plot coordinates with
16
optional zoom functionality that doesn't affect statistical computations.
17
18
Parameters:
19
- xlim: tuple, x-axis limits for zooming (min, max)
20
- ylim: tuple, y-axis limits for zooming (min, max)
21
- expand: bool, whether to expand limits to include data
22
23
Note: This coordinate system preserves distances and angles.
24
"""
25
26
def coord_flip(xlim=None, ylim=None, expand=True):
27
"""
28
Flipped coordinate system (swap x and y axes).
29
30
Exchanges the x and y coordinates, effectively rotating the plot 90 degrees.
31
Useful for horizontal bar charts, box plots, and making long labels readable.
32
33
Parameters:
34
- xlim: tuple, limits for original x-axis (becomes y-axis after flip)
35
- ylim: tuple, limits for original y-axis (becomes x-axis after flip)
36
- expand: bool, whether to expand limits
37
38
Note: After flipping, 'x' aesthetics control vertical position and
39
'y' aesthetics control horizontal position.
40
"""
41
42
def coord_fixed(ratio=1, xlim=None, ylim=None, expand=True):
43
"""
44
Fixed aspect ratio coordinate system.
45
46
Maintains a fixed relationship between units on the x and y axes,
47
ensuring specific aspect ratios are preserved.
48
49
Parameters:
50
- ratio: float, aspect ratio (y/x). ratio=1 makes axes equal,
51
ratio=2 makes y-axis twice as long as x-axis
52
- xlim: tuple, x-axis limits
53
- ylim: tuple, y-axis limits
54
- expand: bool, whether to expand limits
55
56
Usage: Essential for maps, scatter plots where distances matter,
57
and any visualization where proportional relationships are important.
58
"""
59
60
def coord_equal(xlim=None, ylim=None, expand=True, ratio=1):
61
"""
62
Equal scale coordinate system (alias for coord_fixed with ratio=1).
63
64
Ensures that one unit on the x-axis is the same length as one unit
65
on the y-axis. Identical to coord_fixed(ratio=1).
66
67
Parameters:
68
- xlim: tuple, x-axis limits
69
- ylim: tuple, y-axis limits
70
- expand: bool, whether to expand limits
71
- ratio: float, aspect ratio (kept for compatibility, default=1)
72
"""
73
74
def coord_trans(x=None, y=None, xlim=None, ylim=None, expand=True):
75
"""
76
Transformed coordinate system.
77
78
Applies transformations to the coordinate axes, allowing for
79
non-linear mappings of data to plot space.
80
81
Parameters:
82
- x: str or transformer, transformation for x-axis
83
('identity', 'log10', 'sqrt', 'reverse', etc.)
84
- y: str or transformer, transformation for y-axis
85
- xlim: tuple, x-axis limits (in transformed space)
86
- ylim: tuple, y-axis limits (in transformed space)
87
- expand: bool, whether to expand limits
88
89
Common transformations:
90
- 'log10': logarithmic transformation
91
- 'sqrt': square root transformation
92
- 'reverse': reverse the axis direction
93
- 'identity': no transformation (default)
94
"""
95
```
96
97
## Usage Patterns
98
99
### Standard Cartesian Coordinates
100
```python
101
# Default coordinate system (usually not specified explicitly)
102
ggplot(data, aes(x='x', y='y')) + \
103
geom_point() + \
104
coord_cartesian()
105
106
# Zoom in on specific region without affecting statistics
107
ggplot(data, aes(x='x', y='y')) + \
108
geom_point() + \
109
geom_smooth(method='lm') + \
110
coord_cartesian(xlim=(2, 8), ylim=(0, 10))
111
```
112
113
### Flipped Coordinates
114
```python
115
# Horizontal bar chart
116
ggplot(data, aes(x='category', y='value')) + \
117
geom_col() + \
118
coord_flip()
119
120
# Horizontal box plots
121
ggplot(data, aes(x='group', y='measurement')) + \
122
geom_boxplot() + \
123
coord_flip()
124
125
# Better label readability
126
ggplot(data, aes(x='long_category_names', y='count')) + \
127
geom_col() + \
128
coord_flip() + \
129
theme(axis_text_y=element_text(hjust=1))
130
```
131
132
### Fixed Aspect Ratios
133
```python
134
# Equal axes for scatter plots where distance matters
135
ggplot(data, aes(x='width', y='height')) + \
136
geom_point() + \
137
coord_equal()
138
139
# Geographic data (approximate equal projection)
140
ggplot(map_data, aes(x='longitude', y='latitude')) + \
141
geom_polygon(aes(group='group'), fill='lightblue', color='black') + \
142
coord_fixed(ratio=1.3) # Adjust for latitude distortion
143
144
# Custom aspect ratio
145
ggplot(data, aes(x='time', y='price')) + \
146
geom_line() + \
147
coord_fixed(ratio=0.5) # Make x-axis twice as long as y-axis
148
```
149
150
### Transformed Coordinates
151
```python
152
# Log-scale coordinates
153
ggplot(data, aes(x='dose', y='response')) + \
154
geom_point() + \
155
geom_smooth() + \
156
coord_trans(x='log10', y='log10')
157
158
# Square root transformation for count data
159
ggplot(data, aes(x='x', y='count')) + \
160
geom_point() + \
161
coord_trans(y='sqrt')
162
163
# Reverse one axis
164
ggplot(data, aes(x='year', y='rank')) + \
165
geom_line() + \
166
coord_trans(y='reverse') # Lower ranks (1, 2, 3) at top
167
```
168
169
### Coordinate System Combinations with Other Elements
170
```python
171
# Flipped coordinates with free scales in facets
172
ggplot(data, aes(x='category', y='value')) + \
173
geom_col() + \
174
facet_wrap('group', scales='free_y') + \
175
coord_flip() + \
176
theme(axis_text_x=element_text(angle=0))
177
178
# Fixed aspect ratio with custom scales
179
ggplot(spatial_data, aes(x='x', y='y', color='elevation')) + \
180
geom_point() + \
181
scale_color_gradient(low='blue', high='red') + \
182
coord_equal() + \
183
theme_void()
184
185
# Transformed coordinates with statistical layers
186
ggplot(data, aes(x='income', y='health_outcome')) + \
187
geom_point(alpha=0.6) + \
188
geom_smooth(method='lm', se=True) + \
189
coord_trans(x='log10') + \
190
scale_x_continuous(breaks=[1000, 10000, 100000],
191
labels=['1K', '10K', '100K'])
192
```
193
194
### Specialized Visualization Patterns
195
```python
196
# Correlation matrix with equal axes
197
correlation_data = data.corr().reset_index().melt(id_vars='index')
198
ggplot(correlation_data, aes(x='index', y='variable', fill='value')) + \
199
geom_tile() + \
200
scale_fill_gradient2(low='blue', high='red', mid='white') + \
201
coord_equal() + \
202
theme(axis_text_x=element_text(angle=45))
203
204
# Time series with custom aspect ratio for trend visibility
205
ggplot(time_data, aes(x='date', y='value')) + \
206
geom_line() + \
207
coord_fixed(ratio=30) # Emphasize changes over time
208
209
# Rank plots with reversed y-axis
210
ggplot(ranking_data, aes(x='year', y='rank', color='country')) + \
211
geom_line(size=1) + \
212
geom_point(size=2) + \
213
coord_trans(y='reverse') + \
214
scale_y_continuous(breaks=range(1, 11))
215
```
216
217
### Map Visualizations
218
```python
219
# World map with appropriate projection approximation
220
ggplot(world_data, aes(x='long', y='lat')) + \
221
geom_polygon(aes(group='group'), fill='lightgray', color='white') + \
222
coord_fixed(ratio=1.3) + \
223
theme_void()
224
225
# Regional map with equal coordinates
226
ggplot(region_data, aes(x='longitude', y='latitude')) + \
227
geom_point(aes(size='population', color='category')) + \
228
coord_equal() + \
229
theme_minimal()
230
```
231
232
### Statistical Plots with Coordinate Transformations
233
```python
234
# Dose-response curves with log transformation
235
ggplot(dose_data, aes(x='dose', y='response', color='treatment')) + \
236
geom_point() + \
237
geom_smooth(method='lm', se=False) + \
238
coord_trans(x='log10') + \
239
scale_x_continuous(trans='log10',
240
breaks=[0.1, 1, 10, 100],
241
labels=['0.1', '1', '10', '100'])
242
243
# Growth curves with log y-axis
244
ggplot(growth_data, aes(x='time', y='size', color='condition')) + \
245
geom_line() + \
246
coord_trans(y='log10') + \
247
labs(y='Size (log scale)')
248
```
249
250
### Advanced Coordinate Usage
251
```python
252
# Combining zoom with transformations
253
ggplot(data, aes(x='x', y='y')) + \
254
geom_point() + \
255
coord_trans(x='sqrt', xlim=(1, 25), ylim=(0, 100))
256
257
# Multiple coordinate adjustments for complex layouts
258
ggplot(data, aes(x='category', y='value')) + \
259
geom_boxplot() + \
260
facet_wrap('treatment') + \
261
coord_flip() + \
262
theme(strip_text_x=element_text(angle=0))
263
```
264
265
## Important Notes
266
267
### Coordinate vs Scale Transformations
268
```python
269
# Scale transformation (affects statistics)
270
ggplot(data, aes(x='x', y='y')) + \
271
geom_point() + \
272
geom_smooth(method='lm') + \
273
scale_x_log10() # Statistics computed on log-transformed data
274
275
# Coordinate transformation (affects display only)
276
ggplot(data, aes(x='x', y='y')) + \
277
geom_point() + \
278
geom_smooth(method='lm') + \
279
coord_trans(x='log10') # Statistics computed on original data, display transformed
280
```
281
282
### Aspect Ratio Considerations
283
```python
284
# Fixed aspect ratios may require plot size adjustments
285
plot = ggplot(data, aes(x='x', y='y')) + \
286
geom_point() + \
287
coord_equal()
288
289
# Save with appropriate dimensions
290
plot.save('equal_aspect.png', width=8, height=8) # Square for equal aspect
291
```
292
293
### Axis Limits in Different Coordinate Systems
294
```python
295
# Cartesian zoom (doesn't affect data range for statistics)
296
coord_cartesian(xlim=(0, 10))
297
298
# Scale limits (removes data outside range before statistics)
299
scale_x_continuous(limits=(0, 10))
300
301
# Coordinate transformation limits (applied after transformation)
302
coord_trans(x='log10', xlim=(0, 2)) # Limits on log10-transformed values
303
```