Skip to content

python: bypass plotnine auto-closing comms #7657

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

isabelizimm
Copy link
Contributor

@isabelizimm isabelizimm commented May 13, 2025

Release Notes

New Features

  • N/A

Bug Fixes

QA Notes

pip install plotnine

from plotnine import ggplot, geom_point, aes, stat_smooth, facet_wrap
from plotnine.data import mtcars

(
    ggplot(mtcars, aes("wt", "mpg", color="factor(gear)"))
    + geom_point()
    + stat_smooth(method="lm")
    + facet_wrap("gear")
)

Should create 1 plot with no errors. You can also check that in the logs, the plot comms are being used, rather than display_data

Copy link

github-actions bot commented May 13, 2025

E2E Tests 🚀
This PR will run tests tagged with: @:critical

readme  valid tags

def __call__(self, obj):
"""Compute the format for an object."""
try:
if obj.__module__ == "plotnine.ggplot":
Copy link
Contributor Author

@isabelizimm isabelizimm May 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're special casing plotnine here since there is autoplot opening/closing code that causes Positron's plots comm to be closed and the plot gets sent over a more vanilla "display_data" call. When the get_intrinsic_size RPC call was made, we were getting an error since there was no longer a Positron comm to look for.

We've been able to patch other packages in the posit/patches/ directory, but this requires an interception of _ipython_display_() , not really a patch to the code itself. What do people think about this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good solution!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems totally reasonable to me given we already are doing non-standard stuff with the comms.

@isabelizimm
Copy link
Contributor Author

wip for feedback, but i'll add a test before we merge this

Copy link
Contributor

@austin3dickey austin3dickey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find! This branch seems to fix the weirdness in the linked issue.

@isabelizimm isabelizimm marked this pull request as ready for review May 14, 2025 20:13
@isabelizimm isabelizimm requested a review from seeM May 14, 2025 20:14
nstrayer
nstrayer previously approved these changes May 15, 2025
Copy link
Contributor

@nstrayer nstrayer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works great for me! This feels about as surgical as it could get in this case!

def __call__(self, obj):
"""Compute the format for an object."""
try:
if obj.__module__ == "plotnine.ggplot":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems totally reasonable to me given we already are doing non-standard stuff with the comms.

seeM
seeM previously approved these changes May 15, 2025
Comment on lines +243 to +257
if self.enabled:
# lookup registered printer
try:
printer = self.lookup(obj)
except KeyError:
pass
else:
printer(obj)
return True
# Finally look for special method names
method = dir2.get_real_method(obj, self.print_method)
if method is not None:
method()
return True
return True
Copy link
Contributor

@seeM seeM May 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we call super here instead of inlining that code?

@catch_format_error
def __call__(self, obj):
"""Compute the format for an object."""
try:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this also be wrapped in if self.enabled? I'm not really sure how these work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking into this! I am also seeing different plots than anticipated for the retina setting in plotnine, which is maybe related 👀

…n_ipkernel.py

Co-authored-by: Wasim Lorgat <[email protected]>
Signed-off-by: Isabel Zimmerman <[email protected]>
@isabelizimm isabelizimm dismissed stale reviews from seeM and nstrayer via b472a9a May 15, 2025 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants