|
94 | 94 | fig, axs = plot.subplots(ncols=2, share=False) |
95 | 95 | x = np.linspace(-5, 5, N) |
96 | 96 | y = state.rand(N, 5) |
97 | | - axs.format(xlabel='xlabel', ylabel='ylabel', ymargin=0.05) |
| 97 | + axs.format(xlabel='xlabel', ylabel='ylabel') |
98 | 98 | axs.format(suptitle='Standardized arguments demonstration') |
99 | 99 |
|
100 | 100 | # Plot by passing both x and y coordinates |
|
182 | 182 | # %% [raw] raw_mimetype="text/restructuredtext" |
183 | 183 | # .. _ug_errorbars: |
184 | 184 | # |
185 | | -# Adding error bars |
186 | | -# ----------------- |
| 185 | +# Error bars and shading |
| 186 | +# ---------------------- |
187 | 187 | # |
188 | | -# The `~proplot.axes.add_errorbars` wrapper lets you draw error bars |
189 | | -# on-the-fly by passing certain keyword arguments to |
| 188 | +# The `~proplot.axes.indicate_error` wrapper lets you draw error bars |
| 189 | +# and error shading on-the-fly by passing certain keyword arguments to |
190 | 190 | # `~matplotlib.axes.Axes.plot`, `~matplotlib.axes.Axes.scatter`, |
191 | 191 | # `~matplotlib.axes.Axes.bar`, or `~matplotlib.axes.Axes.barh`. |
192 | 192 | # |
193 | 193 | # If you pass 2D arrays to these methods with ``means=True`` or |
194 | 194 | # ``medians=True``, the means or medians of each column are drawn as points, |
195 | | -# lines, or bars, and error bars are drawn to represent the spread in each |
196 | | -# column. `~proplot.axes.add_errorbars` lets you draw both thin error |
197 | | -# "bars" with optional whiskers, and thick error "boxes" overlayed on top of |
198 | | -# these bars (this can be used to represent different percentil ranges). |
199 | | -# Instead of using 2D arrays, you can also pass error bar coordinates |
200 | | -# *manually* with the `bardata` and `boxdata` keyword arguments. See |
201 | | -# `~proplot.axes.add_errorbars` for details. |
| 195 | +# lines, or bars, and error bars or shading is drawn to represent the spread in |
| 196 | +# each column. `~proplot.axes.indicate_error` lets you draw thin error |
| 197 | +# bars with optional whiskers, thick "boxes" overlayed on top of these bars |
| 198 | +# (think of this as a miniature boxplot), or up to 2 intervals of shading. |
| 199 | +# Instead of using 2D arrays, you can also pass the error bounds |
| 200 | +# *manually* with the `bardata`, `boxdata`, `shadedata`, and `fadedata` keyword |
| 201 | +# arguments. See `~proplot.axes.indicate_error` for details. |
202 | 202 |
|
203 | | -# %% |
204 | 203 | import proplot as plot |
205 | 204 | import numpy as np |
206 | 205 | import pandas as pd |
207 | 206 | plot.rc['title.loc'] = 'uc' |
208 | | -plot.rc['axes.ymargin'] = plot.rc['axes.xmargin'] = 0.05 |
| 207 | + |
| 208 | +# Generate sample data |
209 | 209 | state = np.random.RandomState(51423) |
210 | | -data = ( |
211 | | - state.rand(20, 8).cumsum(axis=0).cumsum(axis=1)[:, ::-1] |
212 | | - + 20 * state.normal(size=(20, 8)) + 30 |
213 | | -) |
| 210 | +data = state.rand(20, 8).cumsum(axis=0).cumsum(axis=1)[:, ::-1] |
| 211 | +data = data + 20 * state.normal(size=(20, 8)) + 30 |
| 212 | +data = pd.DataFrame(data, columns=np.arange(0, 16, 2)) |
| 213 | +data.name = 'variable' |
| 214 | + |
| 215 | +# Generate figure |
214 | 216 | fig, axs = plot.subplots( |
215 | 217 | nrows=3, aspect=1.5, axwidth=4, |
216 | 218 | share=0, hratios=(2, 1, 1) |
217 | 219 | ) |
218 | | -axs.format(suptitle='Error bars with various plotting commands') |
| 220 | +axs.format(suptitle='Indicating error bounds with various plotting commands') |
219 | 221 | axs[1:].format(xlabel='column number', xticks=1, xgrid=False) |
220 | 222 |
|
221 | | -# Asking add_errorbars to calculate bars |
| 223 | +# Automatically calculate medians and display default percentile range |
222 | 224 | ax = axs[0] |
223 | | -obj = ax.barh(data, color='red orange', means=True) |
| 225 | +obj = ax.barh( |
| 226 | + data, color='light red', legend=True, |
| 227 | + medians=True, barpctiles=True, boxpctiles=True |
| 228 | +) |
224 | 229 | ax.format(title='Column statistics') |
225 | 230 | ax.format(ylabel='column number', title='Bar plot', ygrid=False) |
226 | 231 |
|
227 | | -# Showing a standard deviation range instead of percentile range |
| 232 | +# Automatically calculate means and display requested standard deviation range |
228 | 233 | ax = axs[1] |
229 | 234 | ax.scatter( |
230 | | - data, color='k', marker='_', markersize=50, |
231 | | - medians=True, barstd=True, boxes=False, capsize=2, |
232 | | - barcolor='gray6', barrange=(-1, 1), barzorder=0, barlw=1, |
| 235 | + data, color='denim', marker='x', markersize=8**2, linewidth=0.8, |
| 236 | + means=True, shadestds=(-1, 1), legend='ll', |
233 | 237 | ) |
234 | 238 | ax.format(title='Scatter plot') |
235 | 239 |
|
236 | | -# Supplying error bar data manually |
| 240 | +# Manually supply error bar data and legend labels |
237 | 241 | ax = axs[2] |
238 | | -boxdata = np.percentile(data, (25, 75), axis=0) |
239 | | -bardata = np.percentile(data, (5, 95), axis=0) |
| 242 | +means = data.mean(axis=0) |
| 243 | +means.name = data.name |
| 244 | +shadedata = np.percentile(data, (25, 75), axis=0) # dark shading |
| 245 | +fadedata = np.percentile(data, (5, 95), axis=0) # light shading |
240 | 246 | ax.plot( |
241 | | - data.mean(axis=0), boxes=True, |
242 | | - edgecolor='k', color='gray9', |
243 | | - boxdata=boxdata, bardata=bardata, barzorder=0, |
244 | | - boxcolor='gray7', barcolor='gray7', boxmarker=False, |
| 247 | + means, shadedata=shadedata, fadedata=fadedata, |
| 248 | + color='ocean blue', barzorder=0, boxmarker=False, legend='ll', |
245 | 249 | ) |
246 | 250 | ax.format(title='Line plot') |
247 | 251 | plot.rc.reset() |
|
258 | 262 | # `~proplot.axes.cycle_changer`, and `~proplot.axes.standardize_1d`. |
259 | 263 | # You can now *group* or *stack* columns of data by passing 2D arrays to |
260 | 264 | # `~matplotlib.axes.Axes.bar` or `~matplotlib.axes.Axes.barh`, just like in |
261 | | -# `pandas`. Also, `~matplotlib.axes.Axes.bar` and `~matplotlib.axes.Axes.barh` |
262 | | -# now employ "default" *x* coordinates if you failed to provide them |
263 | | -# explicitly, just like `~matplotlib.axes.Axes.plot`. |
| 265 | +# `pandas`, or use different colors for negative and positive bars by |
| 266 | +# passing ``negpos=True``. Also, `~matplotlib.axes.Axes.bar` and |
| 267 | +# `~matplotlib.axes.Axes.barh` now employ "default" *x* coordinates if you |
| 268 | +# failed to provide them explicitly. |
264 | 269 | # |
265 | 270 | # To make filled "area" plots, use the new `~proplot.axes.Axes.area` and |
266 | 271 | # `~proplot.axes.Axes.areax` methods. These are alises for |
|
270 | 275 | # `~proplot.axes.fill_betweenx_wrapper`. You can now *stack* or *overlay* |
271 | 276 | # columns of data by passing 2D arrays to `~proplot.axes.Axes.area` and |
272 | 277 | # `~proplot.axes.Axes.areax`, just like in `pandas`. You can also now draw |
273 | | -# area plots that *change color* when the fill boundaries cross each other by |
| 278 | +# area plots that change color when the fill boundaries cross each other by |
274 | 279 | # passing ``negpos=True`` to `~matplotlib.axes.Axes.fill_between`. The most |
275 | 280 | # common use case for this is highlighting negative and positive areas with |
276 | 281 | # different colors, as shown below. |
|
280 | 285 | import numpy as np |
281 | 286 | import pandas as pd |
282 | 287 | plot.rc.titleloc = 'uc' |
283 | | -plot.rc.margin = 0.05 |
284 | 288 | fig, axs = plot.subplots(nrows=2, aspect=2, axwidth=5, share=0, hratios=(3, 2)) |
285 | 289 | state = np.random.RandomState(51423) |
286 | 290 | data = state.rand(5, 5).cumsum(axis=0).cumsum(axis=1)[:, ::-1] |
|
313 | 317 | # %% |
314 | 318 | import proplot as plot |
315 | 319 | import numpy as np |
316 | | -plot.rc.margin = 0 |
317 | | -fig, axs = plot.subplots(array=[[1, 2], [3, 3]], hratios=(1, 0.8), share=0) |
318 | | -axs.format(xlabel='xlabel', ylabel='ylabel', suptitle='Area plot demo') |
| 320 | +fig, axs = plot.subplots(array=[[1, 2], [3, 3]], hratios=(1, 1.5), share=0) |
| 321 | +axs.format(grid=False, xlabel='xlabel', ylabel='ylabel', suptitle='Area plot demo') |
319 | 322 | state = np.random.RandomState(51423) |
320 | 323 | data = state.rand(5, 3).cumsum(axis=0) |
321 | 324 | cycle = ('gray3', 'gray5', 'gray7') |
322 | 325 |
|
323 | | -# Overlaid and stacked area patches |
| 326 | +# Overlaid area patches |
324 | 327 | ax = axs[0] |
325 | 328 | ax.area( |
326 | | - np.arange(5), data, data + state.rand(5)[:, None], cycle=cycle, alpha=0.5, |
| 329 | + np.arange(5), data, data + state.rand(5)[:, None], cycle=cycle, alpha=0.7, |
327 | 330 | legend='uc', legend_kw={'center': True, 'ncols': 2, 'labels': ['z', 'y', 'qqqq']}, |
328 | 331 | ) |
329 | 332 | ax.format(title='Fill between columns') |
| 333 | + |
| 334 | +# Stacked area patches |
330 | 335 | ax = axs[1] |
331 | 336 | ax.area( |
332 | 337 | np.arange(5), data, stacked=True, cycle=cycle, alpha=0.8, |
333 | 338 | legend='ul', legend_kw={'center': True, 'ncols': 2, 'labels': ['z', 'y', 'qqqq']}, |
334 | 339 | ) |
335 | 340 | ax.format(title='Stack between columns') |
336 | 341 |
|
337 | | -# Positive and negative color area patches |
| 342 | +# Positive and negative color bars and area patches |
338 | 343 | ax = axs[2] |
339 | | -data = 5 * (state.rand(20) - 0.5) |
340 | | -ax.area(data, negpos=True, negcolor='blue7', poscolor='red7') |
341 | | -ax.format(title='Positive and negative colors', xlabel='xlabel', ylabel='ylabel') |
342 | | -axs.format(grid=False) |
| 344 | +data = 4 * (state.rand(20) - 0.5) |
| 345 | +ax.bar(data, bottom=-2, width=1, edgecolor='none', negpos=True) |
| 346 | +ax.area(data + 2, y2=2, negpos=True) |
| 347 | +for offset in (-2, 2): |
| 348 | + ax.axhline(offset, color='k', linewidth=1, linestyle='--') |
| 349 | +ax.format( |
| 350 | + xmargin=0, xlabel='xlabel', ylabel='ylabel', |
| 351 | + title='Positive and negative colors demo', titleweight='bold', |
| 352 | +) |
343 | 353 | plot.rc.reset() |
344 | 354 |
|
345 | 355 |
|
|
361 | 371 | import proplot as plot |
362 | 372 | import numpy as np |
363 | 373 | import pandas as pd |
| 374 | + |
| 375 | +# Generate sample data |
364 | 376 | N = 500 |
365 | 377 | state = np.random.RandomState(51423) |
366 | | -fig, axs = plot.subplots(ncols=2, axwidth=2.5) |
367 | 378 | data = state.normal(size=(N, 5)) + 2 * (state.rand(N, 5) - 0.5) * np.arange(5) |
368 | 379 | data = pd.DataFrame( |
369 | 380 | data, |
370 | 381 | columns=pd.Index(['a', 'b', 'c', 'd', 'e'], name='xlabel') |
371 | 382 | ) |
372 | | -axs.format( |
373 | | - ymargin=0.1, xmargin=0.1, grid=False, |
374 | | - suptitle='Boxes and violins demo' |
375 | | -) |
| 383 | + |
| 384 | +# Generate figure |
| 385 | +fig, axs = plot.subplots(ncols=2, axwidth=2.5) |
| 386 | +axs.format(grid=False, suptitle='Boxes and violins demo') |
376 | 387 |
|
377 | 388 | # Box plots |
378 | 389 | ax = axs[0] |
|
428 | 439 | x, y, c, cmap=cmap, lw=7, interp=5, capstyle='round', joinstyle='round' |
429 | 440 | ) |
430 | 441 | ax.format(xlabel='xlabel', ylabel='ylabel', title='Line with smooth gradations') |
431 | | -ax.format(xmargin=0.05, ymargin=0.05) |
432 | 442 | ax.colorbar(m, loc='b', label='parametric coordinate', locator=5) |
433 | 443 |
|
434 | 444 | # Parametric line with stepped gradations |
|
463 | 473 | # `~matplotlib.axes.Axes.scatter` now optionally accepts keywords that look |
464 | 474 | # like `~matplotlib.axes.Axes.plot` keywords (e.g. `color` instead of `c` and |
465 | 475 | # `markersize` instead of `s`). |
466 | | -# |
467 | | -# We are also considering supporting 2D array input and property cycle |
468 | | -# iteration for more obscure matplotlib plotting commands like |
469 | | -# `~matplotlib.axes.Axes.stem`, `~matplotlib.axes.Axes.step`, |
470 | | -# `~matplotlib.axes.Axes.vlines`, and `~matplotlib.axes.Axes.hlines`. Stay |
471 | | -# tuned. |
472 | 476 |
|
473 | 477 | # %% |
474 | 478 | import proplot as plot |
|
0 commit comments