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

PR: Add new options for font size and bottom edge for inline plot #21566

Merged
merged 6 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 3 additions & 3 deletions external-deps/spyder-kernels/.gitrepo

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions external-deps/spyder-kernels/spyder_kernels/console/kernel.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions spyder/config/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-

#
# Copyright © Spyder Project Contributors
# Licensed under the terms of the MIT License
Expand Down Expand Up @@ -151,6 +152,8 @@
'pylab/inline/resolution': 72,
'pylab/inline/width': 6,
'pylab/inline/height': 4,
'pylab/inline/fontsize': 10.0,
'pylab/inline/bottom': 0.11,
'pylab/inline/bbox_inches': True,
'startup/run_lines': '',
'startup/use_run_file': False,
Expand Down
40 changes: 30 additions & 10 deletions spyder/plugins/ipythonconsole/confpage.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,26 @@ def setup_page(self):
_("Height:")+" ", " "+_("inches"),
'pylab/inline/height', min_=1, max_=20, step=1,
tip=_("Default is 4"))
fontsize_spin = self.create_spinbox(
_("Font size:") + " ",
" " + _("points"),
'pylab/inline/fontsize',
min_=5,
max_=48,
step=1.0,
tip=_("Default is 10")
)
bottom_spin = self.create_spinbox(
_("Bottom edge:") + " ",
" " + _("of figure height"),
'pylab/inline/bottom',
min_=0,
max_=0.3,
step=0.01,
tip=_("The position of the bottom edge of the subplots,\nas a "
"fraction of the figure height.\nThe default is 0.11.")
)
bottom_spin.spinbox.setDecimals(2)
bbox_inches_box = newcb(
_("Use a tight layout for inline plots"),
'pylab/inline/bbox_inches',
Expand All @@ -185,16 +205,16 @@ def setup_page(self):
inline_layout = QGridLayout()
inline_layout.addWidget(format_box.label, 1, 0)
inline_layout.addWidget(format_box.combobox, 1, 1)
inline_layout.addWidget(resolution_spin.plabel, 2, 0)
inline_layout.addWidget(resolution_spin.spinbox, 2, 1)
inline_layout.addWidget(resolution_spin.slabel, 2, 2)
inline_layout.addWidget(width_spin.plabel, 3, 0)
inline_layout.addWidget(width_spin.spinbox, 3, 1)
inline_layout.addWidget(width_spin.slabel, 3, 2)
inline_layout.addWidget(height_spin.plabel, 4, 0)
inline_layout.addWidget(height_spin.spinbox, 4, 1)
inline_layout.addWidget(height_spin.slabel, 4, 2)
inline_layout.addWidget(bbox_inches_box, 5, 0, 1, 4)

spinboxes = [resolution_spin, width_spin, height_spin,
fontsize_spin, bottom_spin]
for counter, spinbox in enumerate(spinboxes):
inline_layout.addWidget(spinbox.plabel, counter + 2, 0)
inline_layout.addWidget(spinbox.spinbox, counter + 2, 1)
inline_layout.addWidget(spinbox.slabel, counter + 2, 2)
inline_layout.addWidget(spinbox.help_label, counter + 2, 3)

inline_layout.addWidget(bbox_inches_box, len(spinboxes) + 2, 0, 1, 4)

inline_h_layout = QHBoxLayout()
inline_h_layout.addLayout(inline_layout)
Expand Down
16 changes: 16 additions & 0 deletions spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import shutil
import sys
from textwrap import dedent
from unittest.mock import patch

# Third party imports
from ipykernel._version import __version__ as ipykernel_version
Expand Down Expand Up @@ -1914,6 +1915,21 @@ def test_restart_intertactive_backend(ipyconsole, qtbot):
assert bool(os.environ.get('BACKEND_REQUIRE_RESTART'))


def test_mpl_conf(ipyconsole, qtbot):
"""
Test that after setting matplotlib-related config options, the member
function send_mpl_backend of the shellwidget is called with the new value.
"""
main_widget = ipyconsole.get_widget()
client = main_widget.get_current_client()
with patch.object(client.shellwidget, 'send_mpl_backend') as mock:
main_widget.set_conf('pylab/inline/fontsize', 20.5)
mock.assert_called_once_with({'pylab/inline/fontsize': 20.5})
with patch.object(client.shellwidget, 'send_mpl_backend') as mock:
main_widget.set_conf('pylab/inline/bottom', 0.314)
mock.assert_called_once_with({'pylab/inline/bottom': 0.314})


@flaky(max_runs=3)
@pytest.mark.no_web_widgets
def test_no_infowidget(ipyconsole):
Expand Down
1 change: 1 addition & 0 deletions spyder/plugins/ipythonconsole/widgets/main_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,7 @@ def change_clients_autocall(self, value):
'pylab', 'pylab/backend', 'pylab/autoload',
'pylab/inline/figure_format', 'pylab/inline/resolution',
'pylab/inline/width', 'pylab/inline/height',
'pylab/inline/fontsize', 'pylab/inline/bottom',
'pylab/inline/bbox_inches'])
def change_possible_restart_and_mpl_conf(self, option, value):
"""
Expand Down
18 changes: 18 additions & 0 deletions spyder/plugins/ipythonconsole/widgets/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,8 @@ def send_mpl_backend(self, option=None):
resolution_n = 'pylab/inline/resolution'
width_n = 'pylab/inline/width'
height_n = 'pylab/inline/height'
fontsize_n = 'pylab/inline/fontsize'
bottom_n = 'pylab/inline/bottom'
bbox_inches_n = 'pylab/inline/bbox_inches'
backend_o = self.get_conf(pylab_backend_n)

Expand Down Expand Up @@ -591,6 +593,22 @@ def send_mpl_backend(self, option=None):
if height_o is not None:
matplotlib_conf[height_n] = height_o

# Font size
fontsize_o = float(self.get_conf(fontsize_n))
if (
fontsize_o is not None
and (option is None or fontsize_n in option)
):
matplotlib_conf[fontsize_n] = fontsize_o

# Bottom part
bottom_o = float(self.get_conf(bottom_n))
if (
bottom_o is not None
and (option is None or bottom_n in option)
):
matplotlib_conf[bottom_n] = bottom_o

# Print figure kwargs
bbox_inches_o = self.get_conf(bbox_inches_n)
if option is None or bbox_inches_n in option:
Expand Down
28 changes: 24 additions & 4 deletions spyder/plugins/variableexplorer/widgets/namespacebrowser.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,13 @@ def plot_in_plots_plugin(self, data, funcname):
import spyder.pyplot as plt
from IPython.core.pylabtools import print_figure

try:
from matplotlib import rc_context
except ImportError:
# Ignore fontsize and bottom options if guiqwt is used
# as plotting library
from contextlib import nullcontext as rc_context

if self.get_conf('pylab/inline/figure_format',
section='ipython_console') == 1:
figure_format = 'svg'
Expand All @@ -498,10 +505,23 @@ def plot_in_plots_plugin(self, data, funcname):
else:
bbox_inches = None

fig, ax = plt.subplots(figsize=(width, height))
getattr(ax, funcname)(data)
image = print_figure(fig, fmt=figure_format, bbox_inches=bbox_inches,
dpi=resolution)
matplotlib_rc = {
jitseniesen marked this conversation as resolved.
Show resolved Hide resolved
'font.size': self.get_conf('pylab/inline/fontsize',
section='ipython_console'),
'figure.subplot.bottom': self.get_conf('pylab/inline/bottom',
section='ipython_console')
}

with rc_context(matplotlib_rc):
fig, ax = plt.subplots(figsize=(width, height))
getattr(ax, funcname)(data)
image = print_figure(
fig,
fmt=figure_format,
bbox_inches=bbox_inches,
dpi=resolution
)

if figure_format == 'svg':
image = image.encode()
self.sig_show_figure_requested.emit(image, mime_type, self.shellwidget)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,37 @@ def test_namespacebrowser_plot_with_mute_inline_plotting_true(
assert blocker.args == expected_args


def test_namespacebrowser_plot_options(namespacebrowser):
"""
Test that font.size and figure.subplot.bottom in matplotlib.rcParams are
set to the values from the Spyder preferences when plotting.
"""
def check_rc(*args):
from matplotlib import rcParams
assert rcParams['font.size'] == 20.5
assert rcParams['figure.subplot.bottom'] == 0.314

namespacebrowser.set_conf('mute_inline_plotting', True, section='plots')
namespacebrowser.plots_plugin_enabled = True
namespacebrowser.set_conf(
'pylab/inline/fontsize', 20.5, section='ipython_console'
)
namespacebrowser.set_conf(
'pylab/inline/bottom', 0.314, section='ipython_console'
)

mock_figure = Mock()
mock_axis = Mock()
mock_png = b'fake png'

with patch('spyder.pyplot.subplots',
return_value=(mock_figure, mock_axis)), \
patch('IPython.core.pylabtools.print_figure',
return_value=mock_png), \
patch.object(mock_axis, 'plot', check_rc):
namespacebrowser.plot([4, 2], 'plot')


def test_namespacebrowser_plot_with_mute_inline_plotting_false(namespacebrowser):
"""
Test that plotting a list from the namespace browser shows a plot if
Expand Down