|
213 | 213 | "raw_mimetype": "text/restructuredtext" |
214 | 214 | }, |
215 | 215 | "source": [ |
216 | | - "The axis scale can be changed with `~proplot.axes.Axes.format` (keyword args `xscale` and `yscale`). You can now configure the ``'log'`` and ``'symlog'`` axis scales with the more sensible `base`, `linthresh`, `linscale`, and `subs`\n", |
217 | | - "keyword args, rather than ``basex``, ``basey``, etc. Also, ProPlot's `~proplot.axistools.AutoFormatter` formatter is used for all axis scales by default; this can be changed e.g. by passing ``yformatter='log'`` to `~proplot.axes.XYAxes.format`. See `~proplot.axistools.Scale`, `~proplot.axistools.LogScale` and `~proplot.axistools.SymmetricalLogScale` for details." |
| 216 | + "The axis scale can be changed with `~proplot.axes.Axes.format` (keyword args `xscale` and `yscale`). ProPlot makes some changes to the axis scale API:\n", |
| 217 | + "\n", |
| 218 | + "* You can now pass scale classes to `~matplotlib.axes.Axes.set_xscale`, `~matplotlib.axes.Axes.set_yscale`, and `~proplot.axes.Axes.format` directly, rather than just strings.\n", |
| 219 | + "* ProPlot `~proplot.axistools.Scale` classes can be instantiated *without* an `~matplotlib.axis.Axis` instance. This is required in matplotlib for backward compatibility reasons.\n", |
| 220 | + "* The ``'log'`` and ``'symlog'`` axis scales can be configured with the more sensible `base`, `linthresh`, `linscale`, and `subs` keyword args, rather than `basex`, `basey`, etc. \n", |
| 221 | + "* The `~proplot.axistools.AutoFormatter` formatter is used for all axis scales by default. This can be changed e.g. by passing ``yformatter='log'`` to `~proplot.axes.XYAxes.format`.\n", |
| 222 | + "* The default minor tick locations for the ``'log'`` and ``'symlog'`` axis scales are now both ``np.arange(1, 10)``. The default \"threshold\" for the ``'symlog'`` axis scale is now ``1``.\n", |
| 223 | + "\n", |
| 224 | + "See `~proplot.axistools.Scale` for details.\n" |
218 | 225 | ] |
219 | 226 | }, |
220 | 227 | { |
|
230 | 237 | "plot.rc.update({'linewidth': 1, 'ticklabelweight': 'bold',\n", |
231 | 238 | " 'axeslabelweight': 'bold'})\n", |
232 | 239 | "f, axs = plot.subplots(ncols=2, nrows=2, axwidth=1.8, share=0)\n", |
233 | | - "axs.format(suptitle='Axis scales demo')\n", |
| 240 | + "axs.format(suptitle='Axis scales demo', ytickminor=True)\n", |
234 | 241 | "# Linear and log scales\n", |
235 | 242 | "axs[0].format(yscale='linear', ylabel='linear scale')\n", |
236 | | - "axs[1].format(ylim=(1e-3, 1e3), yscale='log',\n", |
237 | | - " yscale_kw={'subs': np.arange(1, 10)}, ylabel='log scale')\n", |
| 243 | + "axs[1].format(ylim=(1e-3, 1e3), yscale='log', ylabel='log scale')\n", |
238 | 244 | "axs[:2].plot(np.linspace(0, 1, N), np.linspace(0, 1000, N), lw=lw)\n", |
239 | | - "# Symlog and logit scales\n", |
| 245 | + "# Symlog scale\n", |
240 | 246 | "ax = axs[2]\n", |
241 | | - "ax.format(yscale='symlog', yscale_kw={'linthresh': 1}, ylabel='symlog scale')\n", |
| 247 | + "ax.format(yscale='symlog', ylabel='symlog scale')\n", |
242 | 248 | "ax.plot(np.linspace(0, 1, N), np.linspace(-1000, 1000, N), lw=lw)\n", |
| 249 | + "# Logit scale\n", |
243 | 250 | "ax = axs[3]\n", |
244 | 251 | "ax.format(yscale='logit', ylabel='logit scale')\n", |
245 | 252 | "ax.plot(np.linspace(0, 1, N), np.linspace(0.01, 0.99, N), lw=lw)\n", |
|
259 | 266 | "raw_mimetype": "text/restructuredtext" |
260 | 267 | }, |
261 | 268 | "source": [ |
262 | | - "ProPlot adds several new axis scales. The ``'cutoff'`` scale is great when you have weirdly distributed data (see `~proplot.axistools.CutoffScale`). The ``'sine'`` scale uses the sine function, resulting in an *area weighted* spherical latitude coordinate, and the ``'mercator'`` scale uses the Mercator projection latitude coordinate. The ``'inverse'`` scale is useful when working with spectral data (this is more useful with `~proplot.axes.XYAxes.dualx` and `~proplot.axes.XYAxes.dualy`; see :ref:`Dual unit axes`)." |
| 269 | + "ProPlot adds several new axis scales. The ``'cutoff'`` scale is great when you have unusually distributed data (see `~proplot.axistools.CutoffScale`). The ``'sine'`` scale uses the sine function, resulting in an *area weighted* spherical latitude coordinate, and the ``'mercator'`` scale uses the Mercator projection latitude coordinate. The ``'inverse'`` scale is useful when working with spectral data (this is more useful with `~proplot.axes.XYAxes.dualx` and `~proplot.axes.XYAxes.dualy`; see :ref:`Dual unit axes`)." |
263 | 270 | ] |
264 | 271 | }, |
265 | 272 | { |
|
296 | 303 | " ax.format(xscale=('cutoff', *iargs), title=title,\n", |
297 | 304 | " xlim=(0, 4*np.pi), ylabel='wave amplitude',\n", |
298 | 305 | " xformatter='pi', xlocator=locator,\n", |
299 | | - " xtickminor=False, xgrid=True, ygrid=False, suptitle='Cutoff scales demo')" |
| 306 | + " xtickminor=False, xgrid=True, ygrid=False, suptitle='Cutoff axis scales demo')" |
300 | 307 | ] |
301 | 308 | }, |
302 | 309 | { |
|
308 | 315 | "import proplot as plot\n", |
309 | 316 | "import numpy as np\n", |
310 | 317 | "plot.rc.reset()\n", |
311 | | - "f, axs = plot.subplots(nrows=3, ncols=2, axwidth=1.5, share=0)\n", |
312 | | - "axs.format(rowlabels=[\n", |
313 | | - " 'Power\\nscales', 'Exponential\\nscales', 'Geographic\\nscales'], suptitle='Esoteric axis scales demo')\n", |
| 318 | + "f, axs = plot.subplots(nrows=2, ncols=3, axwidth=1.6, share=0, order='F')\n", |
| 319 | + "axs.format(collabels=['Power scales', 'Exponential scales', 'Cartographic scales'],\n", |
| 320 | + " suptitle='Additional axis scales demo')\n", |
314 | 321 | "x = np.linspace(0, 1, 50)\n", |
315 | 322 | "y = 10*x\n", |
316 | 323 | "state = np.random.RandomState(51423)\n", |
|
336 | 343 | "data = state.rand(len(x), len(y2))\n", |
337 | 344 | "for ax, scale, color in zip(axs[4:], ('sine', 'mercator'), ('coral', 'sky blue')):\n", |
338 | 345 | " ax.plot(x, y, '-', color=color, lw=4)\n", |
339 | | - " # Use 'right' to trim the colormap from 0-1 color range to 0-0.8 color range\n", |
340 | 346 | " ax.pcolormesh(x, y2, data, cmap='grays', cmap_kw={'right': 0.8})\n", |
341 | 347 | " ax.format(title=scale.title() + ' y-axis', yscale=scale,\n", |
342 | 348 | " ytickloc='left',\n", |
343 | | - " yformatter='deglat', grid=False, ylocator=20,\n", |
| 349 | + " yformatter='deg', grid=False, ylocator=20,\n", |
344 | 350 | " xscale='linear', xlim=None, ylim=(-85, 85))" |
345 | 351 | ] |
346 | 352 | }, |
|
357 | 363 | "raw_mimetype": "text/restructuredtext" |
358 | 364 | }, |
359 | 365 | "source": [ |
360 | | - "The new `~proplot.axes.XYAxes.dualx` and `~proplot.axes.XYAxes.dualy` methods build duplicate *x* and *y* axes meant to represent *alternate units* in the same coordinate range as the \"parent\" axis. Both `~proplot.axes.XYAxes.dualx` and `~proplot.axes.XYAxes.dualy` accept either a *linear function*, a pair of arbitrary *forward and inverse* functions, or a *scale name or class*. In the latter case, the scale is passed to `~proplot.axistools.Scale` and its transforms are used for the forward and inverse functions." |
| 366 | + "The new `~proplot.axes.XYAxes.dualx` and `~proplot.axes.XYAxes.dualy` methods build duplicate *x* and *y* axes meant to represent *alternate units* in the same coordinate range as the \"parent\" axis. Both `~proplot.axes.XYAxes.dualx` and `~proplot.axes.XYAxes.dualy` accept either a single linear *forward function*, a pair of arbitrary *forward and inverse functions*, or a *scale name or scale class*. In the latter case, the scale is passed to `~proplot.axistools.Scale`, its transforms are used for the forward and inverse functions, and its default locators and formatters are used for the `~proplot.axistools.FuncScale` default locators and formatters.\n", |
| 367 | + "\n", |
| 368 | + "Notably, the \"parent\" axis scale is now *arbitrary*. Below, in the first example, we draw \"dual unit\" axes with both *linear* and *symlog* parent scales. The next two examples demonstrate how to use specialized axis scales used for the forward and inverse transforms of the dual axes." |
361 | 369 | ] |
362 | 370 | }, |
363 | 371 | { |
|
368 | 376 | "source": [ |
369 | 377 | "import proplot as plot\n", |
370 | 378 | "plot.rc.update({'grid.alpha': 0.4, 'linewidth': 1, 'grid.linewidth': 1})\n", |
371 | | - "f, axs = plot.subplots(ncols=2, share=0, aspect=2.2, axwidth=3)\n", |
| 379 | + "c1 = plot.shade('cerulean', 0.5)\n", |
| 380 | + "c2 = plot.shade('red', 0.5)\n", |
| 381 | + "f, axs = plot.subplots([[1, 1, 2, 2], [0, 3, 3, 0]],\n", |
| 382 | + " share=0, aspect=2.2, axwidth=3)\n", |
| 383 | + "axs.format(suptitle='Duplicate axes with custom transformations',\n", |
| 384 | + " xcolor=c1, gridcolor=c1,\n", |
| 385 | + " ylocator=[], yformatter=[])\n", |
372 | 386 | "# Meters and kilometers\n", |
373 | 387 | "ax = axs[0]\n", |
374 | | - "c1, c2 = plot.shade('cerulean', 0.5), plot.shade('red', 0.5)\n", |
375 | | - "ax.format(yformatter='null', xlabel='meters', xlocator=1000, xlim=(0, 5000),\n", |
376 | | - " xcolor=c2, ylocator=[], gridcolor=c2,\n", |
377 | | - " suptitle='Duplicate axes with custom transformations')\n", |
378 | | - "ax.dualx(lambda x: x*1e-3, label='kilometers', grid=True, color=c1)\n", |
| 388 | + "ax.format(xlim=(0, 5000), xlabel='meters')\n", |
| 389 | + "ax.dualx(lambda x: x*1e-3, label='kilometers',\n", |
| 390 | + " grid=True, color=c2, gridcolor=c2)\n", |
379 | 391 | "# Kelvin and Celsius\n", |
380 | 392 | "ax = axs[1]\n", |
381 | | - "ax.format(yformatter='null', xlabel='temperature (K)', title='', xlim=(200, 300), ylocator='null',\n", |
382 | | - " xcolor=c2, gridcolor=c2)\n", |
383 | | - "ax.dualx(lambda x: x - 273.15,\n", |
384 | | - " label='temperature (\\N{DEGREE SIGN}C)', grid=True, color=c1, gridcolor=c1)\n", |
| 393 | + "ax.format(xlim=(200, 300), xlabel='temperature (K)')\n", |
| 394 | + "ax.dualx(lambda x: x - 273.15, label='temperature (\\N{DEGREE SIGN}C)',\n", |
| 395 | + " grid=True, color=c2, gridcolor=c2)\n", |
| 396 | + "# With symlog parent\n", |
| 397 | + "ax = axs[2]\n", |
| 398 | + "ax.format(xlim=(-100, 100), xscale='symlog', xlabel='MegaJoules')\n", |
| 399 | + "ax.dualx(lambda x: x*1e6, label='Joules', formatter='log',\n", |
| 400 | + " grid=True, color=c2, gridcolor=c2)\n", |
385 | 401 | "plot.rc.reset()" |
386 | 402 | ] |
387 | 403 | }, |
|
400 | 416 | "ax = axs[0]\n", |
401 | 417 | "ax.format(xformatter='null', ylabel='pressure (hPa)',\n", |
402 | 418 | " ylim=(1000, 10), xlocator=[], ycolor=c1, gridcolor=c1)\n", |
403 | | - "ax.dualy('height', label='height (km)', ticks=2.5,\n", |
| 419 | + "scale = plot.Scale('height')\n", |
| 420 | + "ax.dualy(scale, label='height (km)', ticks=2.5,\n", |
404 | 421 | " color=c2, gridcolor=c2, grid=True)\n", |
405 | 422 | "ax = axs[1] # span\n", |
406 | 423 | "ax.format(xformatter='null', ylabel='height (km)', ylim=(0, 20), xlocator='null',\n", |
407 | 424 | " grid=True, gridcolor=c2, ycolor=c2)\n", |
408 | | - "ax.dualy('pressure', label='pressure (hPa)', locator=100,\n", |
| 425 | + "scale = plot.Scale('pressure')\n", |
| 426 | + "ax.dualy(scale, label='pressure (hPa)', locator=100,\n", |
409 | 427 | " color=c1, gridcolor=c1, grid=True)\n", |
410 | 428 | "plot.rc.reset()" |
411 | 429 | ] |
|
429 | 447 | "ax.axvline(cutoff, lw=2, ls='-', color=c2)\n", |
430 | 448 | "ax.fill_between([cutoff - 0.03, cutoff + 0.03], 0, 1, color=c2, alpha=0.3)\n", |
431 | 449 | "ax.plot(x, response, color=c1, lw=2)\n", |
432 | | - "ax.format(xlabel='wavenumber (days$^{-1}$)', ylabel='response', gridminor=True)\n", |
433 | | - "ax = ax.dualx('inverse', locator=[\n", |
434 | | - " 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05], label='period (days)')\n", |
| 450 | + "ax.format(xlabel='wavenumber (days$^{-1}$)', ylabel='response', grid=False)\n", |
| 451 | + "scale = plot.Scale('inverse')\n", |
| 452 | + "ax = ax.dualx(scale, locator='log', locator_kw={'subs': (1, 2, 5)}, label='period (days)')\n", |
435 | 453 | "ax.format(title='Imaginary response function',\n", |
436 | 454 | " suptitle='Duplicate axes with wavenumber and period')\n", |
437 | 455 | "plot.rc.reset()" |
|
0 commit comments