-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Dataset.plot.quiver #4407
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
Dataset.plot.quiver #4407
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
cb4d48f
First attempt at quiver plot.
dcherian fbca40e
Support for quiver key
dcherian fc8ad67
refactor out adjusting subplots for legend
dcherian 190d788
Adjust figure for quiverkey.
dcherian 51cb73e
Update quiverkey
dcherian 9cb6a61
Autoscale quiver facetgrid
dcherian c2dcc1d
Support for hue
dcherian 0393e66
fix tests.
dcherian 8116ec9
Fix test
dcherian 04f64c5
Adding docs
dcherian abcc008
small fixes
dcherian f1da0c0
Start adding tests
dcherian 39545b1
Simple tests.
dcherian b6c1bc8
[skip-ci] Start adding docs.
dcherian 7b55945
[skip-ci] add whats-new
dcherian 0da3540
Add quiverkey test
dcherian bc78582
Add test for hue_style
dcherian d1e028c
small doc updates.
dcherian 94f8396
remove commented out autoscaling code
dcherian de48d51
Raise if u,v are provided for non-quiver plots.
dcherian e795672
Fix tests
dcherian e0f227f
Merge remote-tracking branch 'upstream/master' into dataset/quiver
dcherian 8a3912c
[skip-ci] fix bad merge.
dcherian 3685f14
Merge branch 'master' into dataset/quiver
dcherian ca00bd4
[skip-ci] update whats-new
dcherian d2cf58c
[skip-ci] Apply suggestions from code review
dcherian b9bcada
review comments.
dcherian 2b1bc32
Merge remote-tracking branch 'upstream/master' into dataset/quiver
dcherian File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
|
||
from ..core.formatting import format_item | ||
from .utils import ( | ||
_get_nice_quiver_magnitude, | ||
_infer_xy_labels, | ||
_process_cmap_cbar_kwargs, | ||
import_matplotlib_pyplot, | ||
|
@@ -195,7 +196,11 @@ def __init__( | |
self.axes = axes | ||
self.row_names = row_names | ||
self.col_names = col_names | ||
|
||
# guides | ||
self.figlegend = None | ||
self.quiverkey = None | ||
self.cbar = None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. technically backwards incompatible but I'm not sure it affects anyone. |
||
|
||
# Next the private variables | ||
self._single_group = single_group | ||
|
@@ -327,14 +332,15 @@ def map_dataset( | |
from .dataset_plot import _infer_meta_data, _parse_size | ||
|
||
kwargs["add_guide"] = False | ||
kwargs["_is_facetgrid"] = True | ||
|
||
if kwargs.get("markersize", None): | ||
kwargs["size_mapping"] = _parse_size( | ||
self.data[kwargs["markersize"]], kwargs.pop("size_norm", None) | ||
) | ||
|
||
meta_data = _infer_meta_data(self.data, x, y, hue, hue_style, add_guide) | ||
meta_data = _infer_meta_data( | ||
self.data, x, y, hue, hue_style, add_guide, funcname=func.__name__ | ||
) | ||
kwargs["meta_data"] = meta_data | ||
|
||
if hue and meta_data["hue_style"] == "continuous": | ||
|
@@ -344,6 +350,12 @@ def map_dataset( | |
kwargs["meta_data"]["cmap_params"] = cmap_params | ||
kwargs["meta_data"]["cbar_kwargs"] = cbar_kwargs | ||
|
||
kwargs["_is_facetgrid"] = True | ||
|
||
if func.__name__ == "quiver" and "scale" not in kwargs: | ||
raise ValueError("Please provide scale.") | ||
# TODO: come up with an algorithm for reasonable scale choice | ||
|
||
for d, ax in zip(self.name_dicts.flat, self.axes.flat): | ||
# None is the sentinel value | ||
if d is not None: | ||
|
@@ -365,6 +377,9 @@ def map_dataset( | |
elif meta_data["add_colorbar"]: | ||
self.add_colorbar(label=self._hue_label, **cbar_kwargs) | ||
|
||
if meta_data["add_quiverkey"]: | ||
self.add_quiverkey(kwargs["u"], kwargs["v"]) | ||
|
||
return self | ||
|
||
def _finalize_grid(self, *axlabels): | ||
|
@@ -380,37 +395,39 @@ def _finalize_grid(self, *axlabels): | |
|
||
self._finalized = True | ||
|
||
def add_legend(self, **kwargs): | ||
figlegend = self.fig.legend( | ||
handles=self._mappables[-1], | ||
labels=list(self._hue_var.values), | ||
title=self._hue_label, | ||
loc="center right", | ||
**kwargs, | ||
) | ||
|
||
self.figlegend = figlegend | ||
def _adjust_fig_for_guide(self, guide): | ||
# Draw the plot to set the bounding boxes correctly | ||
self.fig.draw(self.fig.canvas.get_renderer()) | ||
renderer = self.fig.canvas.get_renderer() | ||
self.fig.draw(renderer) | ||
|
||
# Calculate and set the new width of the figure so the legend fits | ||
legend_width = figlegend.get_window_extent().width / self.fig.dpi | ||
guide_width = guide.get_window_extent(renderer).width / self.fig.dpi | ||
figure_width = self.fig.get_figwidth() | ||
self.fig.set_figwidth(figure_width + legend_width) | ||
self.fig.set_figwidth(figure_width + guide_width) | ||
|
||
# Draw the plot again to get the new transformations | ||
self.fig.draw(self.fig.canvas.get_renderer()) | ||
self.fig.draw(renderer) | ||
|
||
# Now calculate how much space we need on the right side | ||
legend_width = figlegend.get_window_extent().width / self.fig.dpi | ||
space_needed = legend_width / (figure_width + legend_width) + 0.02 | ||
guide_width = guide.get_window_extent(renderer).width / self.fig.dpi | ||
space_needed = guide_width / (figure_width + guide_width) + 0.02 | ||
# margin = .01 | ||
# _space_needed = margin + space_needed | ||
right = 1 - space_needed | ||
|
||
# Place the subplot axes to give space for the legend | ||
self.fig.subplots_adjust(right=right) | ||
|
||
def add_legend(self, **kwargs): | ||
self.figlegend = self.fig.legend( | ||
handles=self._mappables[-1], | ||
labels=list(self._hue_var.values), | ||
title=self._hue_label, | ||
loc="center right", | ||
**kwargs, | ||
) | ||
self._adjust_fig_for_guide(self.figlegend) | ||
|
||
def add_colorbar(self, **kwargs): | ||
"""Draw a colorbar""" | ||
kwargs = kwargs.copy() | ||
|
@@ -426,6 +443,26 @@ def add_colorbar(self, **kwargs): | |
) | ||
return self | ||
|
||
def add_quiverkey(self, u, v, **kwargs): | ||
kwargs = kwargs.copy() | ||
|
||
magnitude = _get_nice_quiver_magnitude(self.data[u], self.data[v]) | ||
units = self.data[u].attrs.get("units", "") | ||
self.quiverkey = self.axes.flat[-1].quiverkey( | ||
self._mappables[-1], | ||
X=0.8, | ||
Y=0.9, | ||
U=magnitude, | ||
label=f"{magnitude}\n{units}", | ||
labelpos="E", | ||
coordinates="figure", | ||
) | ||
|
||
# TODO: does not work because self.quiverkey.get_window_extent(renderer) = 0 | ||
# https://github.com/matplotlib/matplotlib/issues/18530 | ||
# self._adjust_fig_for_guide(self.quiverkey.text) | ||
return self | ||
|
||
def set_axis_labels(self, x_var=None, y_var=None): | ||
"""Set axis labels on the left column and bottom row of the grid.""" | ||
if x_var is not None: | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.