Skip to content
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

handle retina/hidpi displays with metadata #918

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

xzackli
Copy link

@xzackli xzackli commented Apr 21, 2020

This implements the handling of hidpi displays for PyPlot (#902) like IPython does. During display, it sends metadata with the PNG images that specify half-height and width, with these dimensions read from the PNG header. See the issue for links to how IPython does it.

To complete this feature, it might be nice to add a PyPlot.retina(true) command which doubles the inline DPI and sets IJulia.retina[].

Example Usage

using IJulia
IJulia.retina[] = true

using PyPlot
plt.plot( sin.(1:0.1:10) )

src/inline.jl Outdated
# PNG header is 8 bytes, 4 byte chunk size, 4 byte IHDR string, 8 bytes for w, h
decoded = base64decode(img[1:32]) # Base64 encodes 6 bits per character
if any(decoded[13:16] .!= b"IHDR") # check if the header looks reasonable
throw(ArgumentError("Base64-encoded PNG has a badly formed header."))
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we should throw an error here; we should let the front end decide what to do with malformed PNG data (i.e. just don't set any metadata).

Copy link
Author

Choose a reason for hiding this comment

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

Makes sense, I'll make this change.

@stevengj
Copy link
Member

I don't understand why this can't be done by the front-end display. It seems weird to do this in the kernel, because the kernel doesn't know anything about the display, and indeed the same kernel may be talking to multiple displays in theory.

@stevengj
Copy link
Member

Is there a Jupyter/Jupyterlab issue for this as a front-end feature?

@xzackli
Copy link
Author

xzackli commented Dec 8, 2020

Is there a Jupyter/Jupyterlab issue for this as a front-end feature?

I've made an issue at jupyterlab/jupyterlab#9440 to see what people think. Maybe it's historical.

@tfiers
Copy link

tfiers commented Jan 11, 2022

A short alternative, for if you only care about retina'ing PyPlot Figures, and don't mind that matplotlib's (figwidth, figheight) is not the exact same as the actual png's:

using IJulia, PyPlot

function IJulia.metadata(x::PyPlot.Figure)
    w, h = (x.get_figwidth(), x.get_figheight()) .* x.get_dpi()
    return Dict("image/png" => Dict("width" => w/2, "height" => h/2))
end

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.

3 participants