Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Final improvements to 1D plotting wrappers #258

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jul 11, 2021
Merged

Final improvements to 1D plotting wrappers #258

merged 11 commits into from
Jul 11, 2021

Conversation

lukelbd
Copy link
Collaborator

@lukelbd lukelbd commented Jul 9, 2021

Resolves #194 (and #229). This is another one of those big "refactor" PRs. There are already a couple of them in the recent commit history -- I've been trying to make plot.py more organized, modular, and, well... less of a clusterf*ck. This will be the final one before the imminent v0.7 release. Here are some notes:

  • The canonical order for 1D plotting wrappers is now switched from plot_specific_wrapper --> standardize_1d --> ... to standardize_1d --> plot_specific_wrapper --> ... . This way I don't have to individually parse positional arguments for each plot_specific_wrapper. Now, the plot_specific_wrappers are all smaller -- they just add keywords and support negpos "negative-positive" plots. Previously I had to put wrappers before standardize to convert keywords like x, ymin, etc. to positional arguments, but now that is handled inside standardize_1d.

  • The standardize_1d and standardize_2d functions now accept a data argument, just like many (all?) matplotlib commands. ProPlot previously disabled this feature. Now, you can use e.g. ax.plot('x', 'y', data=pandas_dataframe) or e.g. ax.contourf('z', data=xarray_dataset) and standardize will retrieve arrays from the dict-like containers. This is arguably a cleaner way to work with DataFrame and DataArray input.

  • All "auto-formatting" is now done in _auto_format_1d and _auto_format_2d (from d335272 on master). There is no longer "auto-formatting" of legends/colorbars in apply_cmap and apply_cycle -- the _auto_format functions just pass those funcs default keyword args. This also lets me enforce consistent type -- _auto_format always spits out numpy ndarrays or masked ndarrays. Makes the remaining wrappers much simpler. I also caught a few edge case bugs while refactoring this stuff.

  • There are new plotting commands plotx and scatterx. They are the same as respective plot and scatter but positional input is either command(x) or command(y, x) and multiple columns of x coordinates are supported. This is analogous to fill_betweenx/areax and barh. This also permits "horizontal-direction" shading (resolves indicate_error for x direction #194) without adding a bunch of keywords to indicate_error.

  • Implementing separate plot and plotx functions let me impose "sticky edges" for line plots (a pet peeve of mine). Now, if you don't specify limits, the default limits of the dependent axis (x for plot, y for plotx) are drawn right up to the line edge rather than having padding. I find this is what I want 99% of the time. Without a dedicated plotx, it would be equally possible to have a plot where y is intended to be the "dependent" axis, so until now I couldn't implement this.

  • The process of wrapping barh is considerably simplified. There are two possible workflows for implementing "horizontal" plotting commands:

    1. Wrap only e.g. plot(), have plotx() point to the wrapped plot() function, and have an undocumented plot() method on base.Axes (or add something to cycle_changer) that reverses positional arguments when it gets a keyword like vert=False.
    2. Wrap both plot() and plotx() with the usual standardize_1d --> ... chain, make their plot_extras wrappers point to a shared function, and have the plotx() method on base.Axes reverse the arguments.

    Previously I used the former approach for barh and latter approach for fill_between/fill_betweenx and vlines/hlines. Now I use the latter approach for everything -- it's much cleaner.

Originally I was thinking I'd need to implement "wrappers" on base.Axes for this system to be sustainable (#45). But I actually really like how plot.py has turned out... Perhaps in #45 (after v0.7) I will simply make the "wrapper" functions hidden and figure out a way to concatenate proplot/matplotlib docstrings on base.Axes instances (so that it's easier for users to learn ProPlot). But as far as additional refactoring goes, the current implementation isn't too bad.

@lukelbd
Copy link
Collaborator Author

lukelbd commented Jul 9, 2021

This PR contains some unrelated commits that I couldn't be bothered to split up (website changes in the first few commits, a couple formatting issues with "demo" functions that I happened to just notice).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

indicate_error for x direction
1 participant