-
Notifications
You must be signed in to change notification settings - Fork 92
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
Bugfix/plot crop #2592
Bugfix/plot crop #2592
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,14 +2,15 @@ | |
# Copyright (C) 2023-2024 Posit Software, PBC. All rights reserved. | ||
# | ||
|
||
import base64 | ||
import codecs | ||
import io | ||
import logging | ||
import pickle | ||
import uuid | ||
from typing import Dict, List, Optional, Tuple | ||
from typing import Dict, List, Optional | ||
|
||
import comm | ||
from IPython.core.formatters import format_display_data | ||
|
||
from .plot_comm import PlotBackendMessageContent, PlotResult, RenderRequest | ||
from .positron_comm import CommMessage, JsonRpcErrorCode, PositronComm | ||
|
@@ -22,7 +23,7 @@ | |
# Matplotlib Default Figure Size | ||
DEFAULT_WIDTH_IN = 6.4 | ||
DEFAULT_HEIGHT_IN = 4.8 | ||
BASE_DPI = 96 | ||
BASE_DPI = 100 | ||
|
||
|
||
class PositronDisplayPublisherHook: | ||
|
@@ -96,12 +97,10 @@ def handle_msg(self, msg: CommMessage[PlotBackendMessageContent], raw_msg: JsonR | |
pixel_ratio = request.params.pixel_ratio or 1.0 | ||
|
||
if width_px != 0 and height_px != 0: | ||
format_dict, md_dict = self._resize_pickled_figure( | ||
pickled, width_px, height_px, pixel_ratio | ||
) | ||
format_dict = self._resize_pickled_figure(pickled, width_px, height_px, pixel_ratio) | ||
data = format_dict["image/png"] | ||
output = PlotResult(data=data, mime_type="image/png").dict() | ||
figure_comm.send_result(data=output, metadata=md_dict) | ||
figure_comm.send_result(data=output, metadata={"mime_type": "image/png"}) | ||
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. Do you know if this 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. I thought this is needed by the Plot Client to construct a suitable data uri for the image? 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. I don't think this is currently used and I was thinking to remove it entirely from the comm definition. It seems that R might use this though? I had changes in Amalthea when I tried regenerating using 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. Or did @seeM mean the metadata property here? 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. Yes I was referring to the |
||
|
||
else: | ||
logger.warning(f"Unhandled request: {request}") | ||
|
@@ -157,7 +156,7 @@ def _resize_pickled_figure( | |
new_height_px: int = 460, | ||
pixel_ratio: float = 1.0, | ||
formats: list = ["image/png"], | ||
) -> Tuple[dict, dict]: | ||
) -> dict: | ||
# Delay importing matplotlib until the kernel and shell has been | ||
# initialized otherwise the graphics backend will be reset to the gui | ||
import matplotlib.pyplot as plt | ||
|
@@ -168,11 +167,13 @@ def _resize_pickled_figure( | |
plt.ioff() | ||
|
||
figure = pickle.loads(codecs.decode(pickled.encode(), "base64")) | ||
figure_buffer = io.BytesIO() | ||
|
||
# Adjust the DPI based on pixel_ratio to accommodate high | ||
# resolution displays... | ||
dpi = BASE_DPI * pixel_ratio | ||
figure.set_dpi(dpi) | ||
figure.set_layout_engine("tight") # eliminates whitespace around the figure | ||
|
||
# ... but use base DPI to convert to inch based dimensions. | ||
width_in, height_in = figure.get_size_inches() | ||
|
@@ -197,14 +198,19 @@ def _resize_pickled_figure( | |
|
||
figure.set_size_inches(width_in, height_in) | ||
|
||
format_dict, md_dict = format_display_data(figure, include=formats, exclude=[]) # type: ignore | ||
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. Can we remove the |
||
# Render the figure to a buffer | ||
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. Do we still need the |
||
# using format_display_data() crops the figure to smaller than requested size | ||
figure.savefig(figure_buffer, format="png") | ||
figure_buffer.seek(0) | ||
image_data = base64.b64encode(figure_buffer.read()).decode() | ||
|
||
format_dict = {"image/png": image_data} | ||
|
||
plt.close(figure) | ||
|
||
if was_interactive: | ||
plt.ion() | ||
|
||
return (format_dict, md_dict) | ||
return format_dict | ||
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. This error is because this function's return annotation is still |
||
|
||
def _is_figure_empty(self, figure): | ||
children = figure.get_children() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this error is also due to the incorrect return type annotation on
_resize_pickled_figure
.