or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

aesthetic-mappings.mdcoordinate-systems.mdcore-plotting.mdfaceting.mdgeometric-objects.mdguides-and-legends.mdindex.mdlabels-and-annotations.mdposition-adjustments.mdsample-datasets.mdscales-and-axes.mdstatistical-transformations.mdthemes-and-styling.mdwatermarks.md

faceting.mddocs/

0

# Faceting

1

2

Faceting creates multiple panels (subplots) to show different subsets of your data based on categorical variables. This powerful technique allows you to explore patterns across groups and compare distributions, trends, and relationships within different data segments. Plotnine provides flexible faceting functions that support both grid and wrap layouts.

3

4

## Capabilities

5

6

### Basic Faceting Functions

7

8

Core functions for creating multi-panel plots based on data groupings.

9

10

```python { .api }

11

def facet_null():

12

"""

13

No faceting (single panel).

14

15

This is the default faceting behavior - creates a single plot panel.

16

Useful for explicitly specifying no faceting when needed.

17

"""

18

19

def facet_wrap(facets, nrow=None, ncol=None, scales='fixed', shrink=True,

20

labeller='label_value', as_table=True, drop=True, dir='h'):

21

"""

22

Wrap 1D ribbon of panels into 2D layout.

23

24

Creates subplots arranged in a rectangular grid based on levels of

25

one or more variables.

26

27

Parameters:

28

- facets: str or list, variables to facet by (e.g., 'var' or ['var1', 'var2'])

29

- nrow: int, number of rows in grid

30

- ncol: int, number of columns in grid

31

- scales: str, whether scales are shared across panels

32

('fixed', 'free', 'free_x', 'free_y')

33

- shrink: bool, whether to shrink scales to fit data in each panel

34

- labeller: str or function, how to format facet labels

35

- as_table: bool, whether to fill panels like a table (top-to-bottom)

36

- drop: bool, whether to drop unused factor levels

37

- dir: str, direction to fill panels ('h' for horizontal, 'v' for vertical)

38

"""

39

40

def facet_grid(rows=None, cols=None, scales='fixed', shrink=True,

41

labeller='label_value', as_table=True, drop=True):

42

"""

43

Create 2D grid of panels based on row and column variables.

44

45

Creates a matrix of subplots where rows represent levels of one variable

46

and columns represent levels of another variable.

47

48

Parameters:

49

- rows: str or list, variable(s) for panel rows

50

- cols: str or list, variable(s) for panel columns

51

- scales: str, scale sharing ('fixed', 'free', 'free_x', 'free_y')

52

- shrink: bool, whether to shrink scales to fit data

53

- labeller: str or function, label formatting

54

- as_table: bool, whether to arrange like table (TRUE: top-to-bottom)

55

- drop: bool, whether to drop unused factor levels

56

"""

57

```

58

59

### Labelling Functions

60

61

Functions for controlling how facet labels are displayed and formatted.

62

63

```python { .api }

64

def labeller(**kwargs):

65

"""

66

Create custom labelling functions for facets.

67

68

Parameters:

69

- **kwargs: variable-specific labellers or general labelling options

70

71

Usage:

72

- labeller(variable=label_both) for specific variable

73

- labeller(.default=label_both) for all variables

74

"""

75

76

def as_labeller(x, default=None):

77

"""

78

Convert various objects to labeller functions.

79

80

Parameters:

81

- x: dict, function, or other object to convert

82

- default: default labeller if conversion fails

83

84

Usage:

85

- as_labeller({'A': 'Group A', 'B': 'Group B'})

86

- as_labeller(lambda x: f'Value: {x}')

87

"""

88

89

def label_value(x):

90

"""

91

Default labeller that shows variable values only.

92

93

Displays just the factor level (e.g., 'A', 'B', 'C').

94

"""

95

96

def label_both(x):

97

"""

98

Labeller that shows both variable names and values.

99

100

Displays variable name and value (e.g., 'group: A', 'group: B').

101

"""

102

103

def label_context(x):

104

"""

105

Context-aware labelling.

106

107

Chooses appropriate labelling based on the faceting context.

108

"""

109

```

110

111

## Usage Patterns

112

113

### Basic Facet Wrap

114

```python

115

# Facet by single variable

116

ggplot(data, aes(x='x', y='y')) + \

117

geom_point() + \

118

facet_wrap('category')

119

120

# Facet by multiple variables

121

ggplot(data, aes(x='x', y='y')) + \

122

geom_point() + \

123

facet_wrap(['category', 'group'])

124

125

# Control layout dimensions

126

ggplot(data, aes(x='x', y='y')) + \

127

geom_point() + \

128

facet_wrap('category', ncol=3)

129

```

130

131

### Facet Grid for Two Variables

132

```python

133

# Rows and columns for different variables

134

ggplot(data, aes(x='x', y='y')) + \

135

geom_point() + \

136

facet_grid(rows='treatment', cols='gender')

137

138

# Facet by rows only (creates vertical strip)

139

ggplot(data, aes(x='x', y='y')) + \

140

geom_point() + \

141

facet_grid(rows='category')

142

143

# Facet by columns only (creates horizontal strip)

144

ggplot(data, aes(x='x', y='y')) + \

145

geom_point() + \

146

facet_grid(cols='group')

147

```

148

149

### Scale Independence

150

```python

151

# Free scales for each panel

152

ggplot(data, aes(x='x', y='y')) + \

153

geom_point() + \

154

facet_wrap('category', scales='free')

155

156

# Free x-axis only

157

ggplot(data, aes(x='x', y='y')) + \

158

geom_point() + \

159

facet_wrap('category', scales='free_x')

160

161

# Free y-axis only

162

ggplot(data, aes(x='x', y='y')) + \

163

geom_point() + \

164

facet_wrap('category', scales='free_y')

165

166

# Fixed scales (default)

167

ggplot(data, aes(x='x', y='y')) + \

168

geom_point() + \

169

facet_wrap('category', scales='fixed')

170

```

171

172

### Custom Labels

173

```python

174

# Custom label dictionary

175

label_dict = {'A': 'Treatment A', 'B': 'Treatment B', 'C': 'Control'}

176

177

ggplot(data, aes(x='x', y='y')) + \

178

geom_point() + \

179

facet_wrap('treatment', labeller=as_labeller(label_dict))

180

181

# Show both variable name and value

182

ggplot(data, aes(x='x', y='y')) + \

183

geom_point() + \

184

facet_wrap('category', labeller=label_both)

185

186

# Custom labeller function

187

def custom_labeller(x):

188

return f'Group {x} Data'

189

190

ggplot(data, aes(x='x', y='y')) + \

191

geom_point() + \

192

facet_wrap('group', labeller=as_labeller(custom_labeller))

193

```

194

195

### Complex Faceting Examples

196

```python

197

# Multiple variables with custom layout

198

ggplot(data, aes(x='value', fill='category')) + \

199

geom_histogram(bins=20) + \

200

facet_wrap(['region', 'year'], ncol=4, scales='free_y') + \

201

theme(strip_text=element_text(size=8))

202

203

# Grid with different aspects

204

ggplot(data, aes(x='date', y='sales')) + \

205

geom_line() + \

206

facet_grid(rows='product', cols='quarter', scales='free') + \

207

theme(axis_text_x=element_text(angle=45))

208

209

# Time series by group

210

ggplot(time_data, aes(x='date', y='value', color='metric')) + \

211

geom_line() + \

212

facet_wrap('country', scales='free_y', ncol=3) + \

213

theme_minimal() + \

214

theme(legend_position='bottom')

215

```

216

217

### Combining with Other Grammar Elements

218

```python

219

# Faceted plot with smoothing

220

ggplot(data, aes(x='x', y='y', color='treatment')) + \

221

geom_point(alpha=0.6) + \

222

geom_smooth(method='lm', se=False) + \

223

facet_wrap('site', scales='free') + \

224

scale_color_brewer(type='qual') + \

225

theme_bw()

226

227

# Box plots across multiple grouping variables

228

ggplot(data, aes(x='treatment', y='response', fill='treatment')) + \

229

geom_boxplot() + \

230

facet_grid(rows='timepoint', cols='gender') + \

231

scale_fill_manual(values=['lightblue', 'lightcoral']) + \

232

theme(legend_position='none')

233

```

234

235

### Handling Missing Combinations

236

```python

237

# Drop unused factor levels (default)

238

ggplot(data, aes(x='x', y='y')) + \

239

geom_point() + \

240

facet_wrap('category', drop=True)

241

242

# Keep unused factor levels (creates empty panels)

243

ggplot(data, aes(x='x', y='y')) + \

244

geom_point() + \

245

facet_wrap('category', drop=False)

246

```

247

248

### Layout Direction Control

249

```python

250

# Fill panels horizontally (default)

251

ggplot(data, aes(x='x', y='y')) + \

252

geom_point() + \

253

facet_wrap('category', nrow=2, dir='h')

254

255

# Fill panels vertically

256

ggplot(data, aes(x='x', y='y')) + \

257

geom_point() + \

258

facet_wrap('category', nrow=2, dir='v')

259

260

# Table-style layout (top-to-bottom, left-to-right)

261

ggplot(data, aes(x='x', y='y')) + \

262

geom_point() + \

263

facet_wrap('category', as_table=True)

264

265

# Non-table layout (bottom-to-top, left-to-right)

266

ggplot(data, aes(x='x', y='y')) + \

267

geom_point() + \

268

facet_wrap('category', as_table=False)

269

```

270

271

### Statistical Plots with Faceting

272

```python

273

# Density plots by group

274

ggplot(data, aes(x='value', fill='category')) + \

275

geom_density(alpha=0.7) + \

276

facet_wrap('region') + \

277

scale_fill_brewer(type='qual') + \

278

theme_minimal()

279

280

# Regression by groups

281

ggplot(data, aes(x='x', y='y')) + \

282

geom_point() + \

283

geom_smooth(method='lm', se=True) + \

284

facet_grid(rows='treatment', cols='timepoint') + \

285

theme_bw()

286

```

287

288

## Advanced Faceting Patterns

289

290

### Using Expressions in Facet Variables

291

```python

292

# Create faceting variable on-the-fly

293

ggplot(data, aes(x='x', y='y')) + \

294

geom_point() + \

295

facet_wrap('value > median(value)', labeller=as_labeller({

296

'True': 'Above Median', 'False': 'Below Median'

297

}))

298

```

299

300

### Combining Different Plot Types Across Panels

301

```python

302

# Different geoms highlight different aspects in each panel

303

ggplot(data, aes(x='x', y='y')) + \

304

geom_point(data=data.query('category == "A"')) + \

305

geom_line(data=data.query('category == "B"')) + \

306

facet_wrap('category', scales='free')

307

```