@@ -328,7 +328,8 @@ class Figure(Element):
328328 A percentage defining the aspect ratio of the Figure.
329329 It will be ignored if height is not None.
330330 title : str, default None
331- Figure title.
331+ Figure title. Also used as the ``title`` attribute (accessible
332+ name) of the iframe when the Figure is displayed in a notebook.
332333 figsize : tuple of two int, default None
333334 If you're a matplotlib addict, you can overwrite width and
334335 height. Values will be converted into pixels in using 60 dpi.
@@ -412,24 +413,37 @@ def render(self, **kwargs) -> str:
412413 def _repr_html_ (self , ** kwargs ) -> str :
413414 """Displays the Figure in a Jupyter notebook."""
414415 html = escape (self .render (** kwargs ))
416+ # Give the iframe an accessible name when a title is set, so it is
417+ # not flagged by "frames must have an accessible name" audits.
418+ title_attr = f' title="{ escape (self .title )} "' if self .title else ""
415419 if self .height is None :
416420 iframe = (
417421 '<div style="width:{width};">'
418422 '<div style="position:relative;width:100%;height:0;padding-bottom:{ratio};">' # noqa
419423 '<span style="color:#565656">Make this Notebook Trusted to load map: File -> Trust Notebook</span>' # noqa
420- '<iframe srcdoc="{html}" style="position:absolute;width:100%;height:100%;left:0;top:0;' # noqa
424+ '<iframe srcdoc="{html}"{title_attr} style="position:absolute;width:100%;height:100%;left:0;top:0;' # noqa
421425 'border:none !important;" '
422426 "allowfullscreen webkitallowfullscreen mozallowfullscreen>"
423427 "</iframe>"
424428 "</div></div>"
425- ).format (html = html , width = self .width , ratio = self .ratio )
429+ ).format (
430+ html = html ,
431+ width = self .width ,
432+ ratio = self .ratio ,
433+ title_attr = title_attr ,
434+ )
426435 else :
427436 iframe = (
428- '<iframe srcdoc="{html}" width="{width}" height="{height}" '
437+ '<iframe srcdoc="{html}"{title_attr} width="{width}" height="{height}" '
429438 'style="border:none !important;" '
430439 "allowfullscreen webkitallowfullscreen mozallowfullscreen>"
431440 "</iframe>"
432- ).format (html = html , width = self .width , height = self .height )
441+ ).format (
442+ html = html ,
443+ width = self .width ,
444+ height = self .height ,
445+ title_attr = title_attr ,
446+ )
433447 return iframe
434448
435449 def add_subplot (self , x : int , y : int , n : int , margin : float = 0.05 ) -> "Div" :
@@ -640,6 +654,10 @@ class IFrame(Element):
640654 height. Values will be converted into pixels in using 60 dpi.
641655 For example figsize=(10, 5) will result in
642656 width="600px", height="300px".
657+ title : str, default None
658+ Value for the iframe's ``title`` attribute, used as the frame's
659+ accessible name. Set it to satisfy accessibility audits that
660+ require every frame to have an accessible name.
643661 """
644662
645663 def __init__ (
@@ -649,10 +667,12 @@ def __init__(
649667 height : Optional [str ] = None ,
650668 ratio : str = "60%" ,
651669 figsize : Optional [Tuple [int , int ]] = None ,
670+ title : Optional [str ] = None ,
652671 ):
653672 super ().__init__ ()
654673 self ._name = "IFrame"
655674
675+ self .title = title
656676 self .width = width
657677 self .height = height
658678 self .ratio = ratio
@@ -671,21 +691,32 @@ def render(self, **kwargs) -> str:
671691 html = "data:text/html;charset=utf-8;base64," + base64 .b64encode (
672692 html .encode ("utf8" ),
673693 ).decode ("utf8" )
694+ title_attr = f' title="{ escape (self .title )} "' if self .title else ""
674695
675696 if self .height is None :
676697 iframe = (
677698 '<div style="width:{width};">'
678699 '<div style="position:relative;width:100%;height:0;padding-bottom:{ratio};">' # noqa
679- '<iframe src="{html}" style="position:absolute;width:100%;height:100%;left:0;top:0;' # noqa
700+ '<iframe src="{html}"{title_attr} style="position:absolute;width:100%;height:100%;left:0;top:0;' # noqa
680701 'border:none !important;">'
681702 "</iframe>"
682703 "</div></div>"
683- ).format (html = html , width = self .width , ratio = self .ratio )
704+ ).format (
705+ html = html ,
706+ width = self .width ,
707+ ratio = self .ratio ,
708+ title_attr = title_attr ,
709+ )
684710 else :
685711 iframe = (
686- '<iframe src="{html}" width="{width}" style="border:none !important;" '
712+ '<iframe src="{html}"{title_attr} width="{width}" style="border:none !important;" '
687713 'height="{height}"></iframe>'
688- ).format (html = html , width = self .width , height = self .height )
714+ ).format (
715+ html = html ,
716+ width = self .width ,
717+ height = self .height ,
718+ title_attr = title_attr ,
719+ )
689720 return iframe
690721
691722
0 commit comments