Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Adding png image return for inline backend figures with _repr_html_#16788

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
tdpetrou wants to merge5 commits intomatplotlib:masterfromtdpetrou:add-repr_html-for-inline-figures
Closed
Show file tree
Hide file tree
Changes from4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletionslib/matplotlib/backend_bases.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1595,6 +1595,73 @@ def __init__(self, figure):
self.toolbar = None # NavigationToolbar2 will set me
self._is_idle_drawing = False

def _repr_html_(self):
if not self.figure.axes and not self.figure.lines:
return

Choose a reason for hiding this comment

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

What if the figure only contains a Rectangle an arrow and a Text?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

True, I copied that from elsewhere. Is there a clean way to determine if the figure has changed at all?

Choose a reason for hiding this comment

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

Checkhttps://matplotlib.org/faq/howto_faq.html#check-whether-a-figure-is-empty
However, maybe even completely empty figures should return some html? After all, you get what you ask for, right?

Copy link
Member

Choose a reason for hiding this comment

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

What do you mean "changed"?

I agree with@ImportanceOfBeingErnest if we are going to have a repr, it should always showsomething even if that something is an empty image.


dpi = self.figure.dpi
is_retina = False

import IPython
ip = IPython.get_ipython()

Choose a reason for hiding this comment

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

This would fail whenever IPython is not available.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

Wouldn't_repr_html_ only get triggered for ipython?

Choose a reason for hiding this comment

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

I guess IPython invented this; but in principle anything can try to call such method if it's available.

Copy link
Member

Choose a reason for hiding this comment

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

The other way you can check this isif 'IPython' in sys.modules. That way if the user has not previously imported IPython we won't do it for them.

ib_list = [c for c in ip.configurables
if 'InlineBackend' in type(c).__name__]

# having an 'inline' backend doesn't mean '%matplotlib inline' has been run
# Running %matplotlib inline runs pylabtools.configure_inline_support
# which appends the InlineBackend to the list of configurables
if get_backend() == 'module://ipykernel.pylab.backend_inline' and ib_list:
ib = ib_list[0]
bbox_inches = ib.print_figure_kwargs['bbox_inches']
fmt = next(iter(ib.figure_formats))
if fmt == 'retina':
is_retina = True
dpi = dpi * 2
fmt = self.get_default_filetype()
else:
bbox_inches = 'tight' # how to let user choose self.figure.bbox_inches?
Copy link
Member

Choose a reason for hiding this comment

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

This just should not be passed or set to None. That IPython inline defaults to'tight' has caused a tremendous amount of confusion over the years.

fmt = self.get_default_filetype()

if fmt not in {'png', 'svg', 'jpg', 'pdf'}:
fmt = 'png'

kw = {
"format":fmt,
"facecolor":self.figure.get_facecolor(),
"edgecolor":self.figure.get_edgecolor(),
"dpi":dpi,
"bbox_inches":bbox_inches,
}

bytes_io = io.BytesIO()
self.print_figure(bytes_io, **kw)
Copy link
Contributor

Choose a reason for hiding this comment

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

you can just pass the kwargs here (having a separate dict doesn't seem to buy much)

Copy link
Contributor

Choose a reason for hiding this comment

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

and you need to force the format here. again, bytes_io could easily contain a postscript image here, for example.

raw_bytes = bytes_io.getvalue()

from IPython.core.display import _pngxy, _jpegxy

if fmt == 'svg':
return raw_bytes.decode()
elif fmt == 'png':
w, h = _pngxy(raw_bytes)
elif fmt == 'jpg':
w, h = _jpegxy(raw_bytes)
elif fmt == 'pdf':
w, h = self.figure.get_size_inches()
w, h = w * dpi, h * dpi

if is_retina:
w, h = w // 2, h // 2

from base64 import b64encode
data = b64encode(raw_bytes).decode()

if fmt == 'png':
return f'<img width="{w}" height="{h}" src="data:image/png;base64, {data}" />'
elif fmt == 'pdf':
return f'<embed width="{w}" height="{h}" src="data:application/pdf;base64, {data}">'
elif fmt == 'jpg':
return f'<img width="{w}" height="{h}" src="data:image/jpeg;base64, {data}" />'

@classmethod
@functools.lru_cache()
def _fix_ipython_backend2gui(cls):
Expand Down
3 changes: 3 additions & 0 deletionslib/matplotlib/backends/backend_webagg.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -51,6 +51,9 @@ def run(self):
class FigureCanvasWebAgg(core.FigureCanvasWebAggCore):
_timer_cls = TimerTornado

def _repr_html_(self):
return ipython_inline_display(self.figure)

def show(self):
# show the figure window
global show # placates pyflakes: created by @_Backend.export below
Expand Down
6 changes: 1 addition & 5 deletionslib/matplotlib/figure.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -369,11 +369,7 @@ def __init__(self,
# use it, for some reason.

def _repr_html_(self):
# We can't use "isinstance" here, because then we'd end up importing
# webagg unconditionally.
if 'WebAgg' in type(self.canvas).__name__:
from matplotlib.backends import backend_webagg
return backend_webagg.ipython_inline_display(self)
return self.canvas._repr_html_()

def show(self, warn=True):
"""
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp