|
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