Skip to content

Commit 2ff082b

Browse files
Multiple plots can be plotted in one window on the first try. Therefore i introduced some way to reorganize the already existing axes in a subtab window.
1 parent aab03e4 commit 2ff082b

File tree

5 files changed

+64
-50
lines changed

5 files changed

+64
-50
lines changed

src/sas/qtgui/MainWindow/DataExplorer.py

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,20 +1076,19 @@ def displayDataByName(self, name=None, is_data=True, id=None):
10761076
# Residuals get their own plot
10771077
if plot.plot_role in [DataRole.ROLE_RESIDUAL, DataRole.ROLE_STAND_ALONE]:
10781078
plot.yscale = 'linear'
1079-
self.plotData([(item, plot)])
1079+
self.plotData([(item, plot)], id)
10801080
else:
10811081
new_plots.append((item, plot))
10821082

10831083
if new_plots:
1084-
self.plotData(new_plots)
1084+
self.plotData(new_plots, id)
10851085

1086-
def displayData(self, data_list, id=None):
1086+
def displayData(self, data_list, id):
10871087
"""
10881088
Forces display of charts for the given data set
10891089
"""
1090-
# data_list = [QStandardItem, [Axes] Data1D/Data2D]
1091-
plots_to_show = data_list[2:]
1092-
tpw_ax = data_list[1]
1090+
# data_list = [QStandardItem, Data1D/Data2D]
1091+
plots_to_show = data_list[1:]
10931092
plot_item = data_list[0]
10941093

10951094
# plots to show
@@ -1110,7 +1109,7 @@ def displayData(self, data_list, id=None):
11101109
if self.isPlotShown(main_data):
11111110
self.active_plots[main_data.name].showNormal()
11121111
else:
1113-
self.plotData([(plot_item, tpw_ax, main_data)])
1112+
self.plotData([(plot_item, main_data)], id)
11141113

11151114
append = False
11161115
plot_to_append_to = None
@@ -1135,7 +1134,7 @@ def displayData(self, data_list, id=None):
11351134
continue
11361135
elif role in stand_alone_types:
11371136
# Stand-alone plots should always be separate
1138-
self.plotData([(plot_item, tpw_ax, plot_to_show)])
1137+
self.plotData([(plot_item, plot_to_show)], id)
11391138
elif append:
11401139
# Assume all other plots sent together should be on the same chart if a previous plot exists
11411140
if not plot_to_append_to:
@@ -1146,8 +1145,8 @@ def displayData(self, data_list, id=None):
11461145
# Plots with main data points on the same chart
11471146
# Get the main data plot unless data is 2D which is plotted earlier
11481147
if main_data is not None and not isinstance(main_data, Data2D):
1149-
new_plots.append((plot_item, tpw_ax, main_data))
1150-
new_plots.append((plot_item, tpw_ax, plot_to_show))
1148+
new_plots.append((plot_item, main_data))
1149+
new_plots.append((plot_item, plot_to_show))
11511150

11521151
if append:
11531152
# Append any plots handled in loop before an existing plot was found
@@ -1157,7 +1156,7 @@ def displayData(self, data_list, id=None):
11571156
new_plots = []
11581157

11591158
if new_plots:
1160-
self.plotData(new_plots)
1159+
self.plotData(new_plots, id)
11611160

11621161
self.parent.tabbedPlotWidget.show_or_activate()
11631162

@@ -1195,18 +1194,22 @@ def addDataPlot2D(self, plot_set, item):
11951194
# sv.show()
11961195
# ============================================
11971196

1198-
def plotData(self, plots, transform=True):
1197+
def plotData(self, plots, tab_id, transform=True):
11991198
"""
12001199
Takes 1D/2D data and generates a single plot (1D) or multiple plots (2D)
12011200
"""
1201+
tab_index = self.parent.tabbedPlotWidget.tab_fitpage_dict[tab_id]
1202+
print("plotData")
12021203
# Call show on requested plots
12031204
# All same-type charts in one plot
1204-
for item, tpw_ax, plot_set in plots:
1205+
for item, plot_set in plots:
12051206
if isinstance(plot_set, Data1D):
12061207
if 'new_plot' not in locals():
12071208
# Create only one PlotterWidget(QWidget) for a number of datasets that are supposed to be shown in
12081209
# the same Widget
1209-
print("created PlotterWidget for:", item)
1210+
self.parent.tabbedPlotWidget.widget(tab_index).add_more_axes()
1211+
tpw_ax = self.parent.tabbedPlotWidget.widget(tab_index).last_axes()
1212+
12101213
new_plot = PlotterWidget(manager=self, parent=self, tpw_ax=tpw_ax)
12111214
new_plot.item = item
12121215
print("plotted plot for:", item)
@@ -1219,7 +1222,6 @@ def plotData(self, plots, transform=True):
12191222
msg = "Incorrect data type passed to Plotting"
12201223
raise AttributeError(msg)
12211224

1222-
print("from DataExplorer.plotData: self.active_plots", self.active_plots)
12231225

12241226
if 'new_plot' in locals() and \
12251227
hasattr(new_plot, 'data') and \
@@ -1295,6 +1297,7 @@ def appendPlot(self):
12951297
@staticmethod
12961298
def appendOrUpdatePlot(self, data, plot):
12971299
name = data.name
1300+
print("append or update plot")
12981301
if isinstance(plot, Plotter2DWidget) or name in plot.plot_dict.keys():
12991302
plot.replacePlot(name, data)
13001303
else:

src/sas/qtgui/Perspectives/Fitting/FittingWidget.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2449,10 +2449,8 @@ def onPlot(self):
24492449
self.cmdPlot.setText("Compute/Plot")
24502450
# Force data recalculation so existing charts are updated
24512451
if not self.data_is_loaded:
2452-
print("showTheoryPlot from FittingWidget")
24532452
self.showTheoryPlot()
24542453
else:
2455-
print("showPlot from FittingWidget")
24562454
self.showPlot()
24572455
# This is an important processEvent.
24582456
# This allows charts to be properly updated in order
@@ -2512,10 +2510,10 @@ def _requestPlots(self, item_name, item_model):
25122510
# send this information to the TabbedPlotWidget so that it can unpack and show the plots as well
25132511
self.parent.tabbedPlotWidget.add_tab(item_name, item_model, self.tab_id)
25142512

2515-
tab_index = self.parent.tabbedPlotWidget.tab_fitpage_dict[self.tab_id]
2516-
tpw_axes = self.parent.tabbedPlotWidget.widget(tab_index).ax
2513+
# tab_index = self.parent.tabbedPlotWidget.tab_fitpage_dict[self.tab_id]
2514+
# self.parent.tabbedPlotWidget.widget(tab_index).add_more_axes
2515+
# tpw_axes = self.parent.tabbedPlotWidget.widget(tab_index).ax
25172516

2518-
print("axes received in FittingWidget:", tpw_axes)
25192517

25202518
fitpage_name = self.kernel_module.name
25212519
plots = GuiUtils.plotsFromDisplayName(item_name, item_model)
@@ -2526,8 +2524,10 @@ def _requestPlots(self, item_name, item_model):
25262524
item, plot = item_plot
25272525
if plot.plot_role != DataRole.ROLE_DATA and fitpage_name in plot.name:
25282526
data_shown = True
2529-
self.communicate.plotRequestedSignal.emit([item, tpw_axes[i], plot], self.tab_id)
2527+
self.communicate.plotRequestedSignal.emit([item, plot], self.tab_id)
25302528
# return the last data item seen, if nothing was plotted; supposed to be just data)
2529+
tab_index = self.parent.tabbedPlotWidget.tab_fitpage_dict[self.tab_id]
2530+
self.parent.tabbedPlotWidget.widget(tab_index).rearrange_plots()
25312531
return None if data_shown else item
25322532

25332533
def onOptionsUpdate(self):

src/sas/qtgui/Plotting/Plotter.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,6 @@ def plot(self, data=None, color=None, marker=None, hide_error=False, transform=T
240240
ax.axhline(y=-1, color='gray', linestyle='--')
241241
# Update the list of data sets (plots) in chart
242242
self.plot_dict[data.name] = data
243-
print("from Plotter: self.plot_dict:", self.plot_dict)
244243

245244
self.plot_lines[data.name] = line
246245

src/sas/qtgui/Plotting/PlotterBase.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def __init__(self, parent=None, manager=None, quickplot=False, tpw_ax=None):
3636
self.quickplot = quickplot
3737

3838
# Set auto layout so x/y axis captions don't get cut off
39-
rcParams.update({'figure.autolayout': True})
39+
# rcParams.update({'figure.autolayout': True})
4040

4141
#plt.style.use('ggplot')
4242
#plt.style.use('seaborn-darkgrid')

src/sas/qtgui/Plotting/SubTabs.py

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from PySide6 import QtCore
33

44
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
5-
from matplotlib.figure import Figure
5+
import matplotlib.pyplot as plt
66

77
from sas.qtgui.Utilities import GuiUtils
88

@@ -36,8 +36,6 @@ def __init__(self, parent: TabbedPlotWidget, plots: list):
3636
def set_parent_tab_index(self):
3737
self.parent_tab_index = self.parent.indexOf(self)
3838
self.tab_id = self.parent.inv_tab_fitpage_dict[self.parent_tab_index]
39-
print(self.parent_tab_index)
40-
print(self.tab_id)
4139

4240
def add_subtab(self, plots):
4341
"""
@@ -62,34 +60,48 @@ def add_subtab(self, plots):
6260
# The idea behind creating the figure here already is to feed it to the creation of the canvas right away,
6361
# because otherwise it can be quite tricky to navigate through all the layers in between to add the figure
6462
# or manipulate all the axes for example
65-
self.figure = Figure(figsize=(5, 5))
66-
67-
# filling the slots for the plots temporary to try out the functionalities of the dock container and the
68-
# clickable canvas
69-
print("subplot_count len(plots)", len(plots))
70-
subplot_count = len(plots)
71-
if subplot_count <= 1:
72-
self.ax = self.figure.subplots(subplot_count)
73-
# putting the axes object in a list so that the access can be generic for both cases with multiple
74-
# subplots and without
75-
self.ax = [self.ax]
76-
else:
77-
# for multiple subplots: decide on the ratios for the bigger, central plot and the smaller, side plots
78-
# region for the big central plot in gridspec
79-
gridspec = self.figure.add_gridspec(ncols=2, width_ratios=[3, 1])
80-
# region for the small side plots in sub_gridspec
81-
sub_gridspec = gridspec[1].subgridspec(ncols=1, nrows=subplot_count-1)
82-
83-
self.ax = [self.figure.add_subplot(gridspec[0])]
84-
# add small plots to axes list, so it can be accessed that way
85-
for idx in range(subplot_count - 1):
86-
self.ax.append(self.figure.add_subplot(sub_gridspec[idx]))
87-
88-
print("axes created in SubTabs:", self.ax[0])
63+
self.figure = plt.figure()
8964

9065
self.addTab(DockContainer(self.figure), str(self.counter))
9166
self.counter += 1
9267

68+
def add_more_axes(self):
69+
"""
70+
Simply adds a new subplot to the figure.
71+
"""
72+
self.figure.add_subplot()
73+
74+
def last_axes(self):
75+
"""
76+
Get the last axes that was created by add_more_axes
77+
"""
78+
return self.figure.get_axes()[-1]
79+
80+
def rearrange_plots(self):
81+
"""
82+
This method is called after plotting the results for this tab. It arranges the plots in two columns with the
83+
big plot on the left side and all the other plots on the right side.
84+
"""
85+
print("rearrange_plots")
86+
axes = self.figure.get_axes()
87+
if len(axes) > 2:
88+
pass # nothing to do, just one plot needs to be shown in the middle
89+
elif len(axes) == 2:
90+
# two column gridspec needs to be applied
91+
self.gs = self.figure.add_gridspec(nrows=1, ncols=2)
92+
93+
# this for loop cannot be replaced by for ax in axes, because the ax is modified in the list :)
94+
for i in range(len(axes)):
95+
axes[i].set_position(self.gs[i].get_position(self.figure))
96+
else:
97+
# subgridspec needs to be applied
98+
self.gs = self.figure.add_gridspec(nrows=1, ncols=2)
99+
self.sub_gs = self.gs[1].subgridspec(ncols=1, nrows=len(axes)-1)
100+
101+
axes[0].set_position(self.gs[0].get_position(self.figure))
102+
for i in range(len(axes)-1):
103+
axes[i+1].set_position(self.gs[i].get_position(self.figure))
104+
93105

94106
class DockContainer(QtWidgets.QMainWindow):
95107
"""

0 commit comments

Comments
 (0)