Skip to content

Commit bc24321

Browse files
authored
Support fig.show() (#22)
* Support fig.show() * isort Signed-off-by: harupy <17039389+harupy@users.noreply.github.com>
1 parent 2808753 commit bc24321

File tree

5 files changed

+112
-1
lines changed

5 files changed

+112
-1
lines changed

docs/source/examples/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ Examples
1313
fig-vars
1414
precode
1515
iframe-size
16+
show

docs/source/examples/show.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
show
2+
====
3+
4+
.. plotly::
5+
6+
import plotly.express as px
7+
8+
fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])
9+
fig.show()
10+
11+
12+
.. plotly::
13+
:fig-vars: figure
14+
15+
import plotly.express as px
16+
17+
figure = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])
18+
figure.show()

sphinx_plotly_directive/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,9 @@
172172
assign_last_line_into_variable,
173173
create_code_block,
174174
create_directive_block,
175+
ends_with_show,
175176
save_plotly_figure,
177+
strip_last_line,
176178
)
177179

178180

@@ -532,7 +534,11 @@ def run_code(code, code_path, ns=None, function_name=None, fig_vars=None):
532534

533535
variable_name = "fig"
534536

535-
if function_name is not None:
537+
if ends_with_show(code):
538+
print(strip_last_line(code))
539+
exec(strip_last_line(code), ns)
540+
figs = [ns[fig_var] for fig_var in fig_vars] if fig_vars else [ns[variable_name]]
541+
elif function_name is not None:
536542
exec(code, ns)
537543
exec(assign_last_line_into_variable(function_name + "()", variable_name), ns)
538544
figs = [ns[variable_name]]

sphinx_plotly_directive/utils.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import re
12
import textwrap
23

34
import plotly
@@ -132,3 +133,60 @@ def create_code_block(code, language=None):
132133
"",
133134
]
134135
)
136+
137+
138+
def strip_last_line(code):
139+
r"""
140+
Strips the last line of the give code block
141+
142+
Parameters
143+
----------
144+
code : str
145+
Code to strip
146+
147+
Returns
148+
-------
149+
str:
150+
Stripped code
151+
152+
Examples
153+
--------
154+
>>> strip_last_line("a")
155+
''
156+
>>> strip_last_line("a\nb")
157+
'a'
158+
>>> strip_last_line("a\nb\nc")
159+
'a\nb'
160+
"""
161+
return "\n".join(code.strip().split("\n")[:-1])
162+
163+
164+
def ends_with_show(code):
165+
r"""
166+
Returns True if the last line of the given code block ends with `show()`
167+
168+
Parameters
169+
----------
170+
code : str
171+
Code that may contain a line that looks like `fig.show()`
172+
173+
Returns
174+
-------
175+
str:
176+
Variable name of the object that calls `show()`
177+
178+
Examples
179+
--------
180+
>>> ends_with_show("fig.show()") # simple
181+
True
182+
>>> ends_with_show("fig.show(1, a=2)") # show with arguments
183+
True
184+
>>> ends_with_show("fig = dummy\nfig.show()\n") # multiline
185+
True
186+
>>> ends_with_show("foo") # doesn't contains `show`
187+
False
188+
"""
189+
# TODO: Use a more strict regular expression
190+
pattern = r"^(.+)\.show\(.*\)$"
191+
match = re.search(pattern, code.strip().split("\n")[-1], flags=re.DOTALL)
192+
return bool(match)

tests/test_utils.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import os
22

33
import plotly.express as px
4+
import pytest
45

56
from sphinx_plotly_directive.utils import (
67
assign_last_line_into_variable,
78
create_code_block,
89
create_directive_block,
10+
ends_with_show,
911
save_plotly_figure,
12+
strip_last_line,
1013
)
1114

1215

@@ -63,3 +66,28 @@ def test_create_code_block():
6366
""".lstrip()
6467

6568
assert create_code_block(code, "python") == expected
69+
70+
71+
@pytest.mark.parametrize(
72+
"code, expected_result",
73+
[
74+
("a", ""),
75+
("a\nb", "a"),
76+
("a\nb\nc", "a\nb"),
77+
],
78+
)
79+
def test_strip_last_line(code, expected_result):
80+
assert strip_last_line(code) == expected_result
81+
82+
83+
@pytest.mark.parametrize(
84+
"code, expected_result",
85+
[
86+
("fig.show()", True), # simple
87+
("fig.show(1, a=2)", True), # contains arguments
88+
("fig = dummy\nfig.show()\n", True), # multiline
89+
("fig", False), # no show
90+
],
91+
)
92+
def test_ends_with_show(code, expected_result):
93+
assert ends_with_show(code) == expected_result

0 commit comments

Comments
 (0)