Add title to pyplot window
When using pyplot to plot the results, the window name is based on the dataset title and the view title.
This commit is contained in:
parent
b15a5424d2
commit
c2e1384a5c
|
@ -17,7 +17,7 @@
|
|||
# along with this msspec. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Source file : src/msspec/iodata.py
|
||||
# Last modified: Mon, 16 Jun 2025 14:42:03 +0200
|
||||
# Last modified: Wed, 18 Jun 2025 11:46:41 +0200
|
||||
# Committed by : Sylvain Tricot <sylvain.tricot@univ-rennes.fr>
|
||||
|
||||
|
||||
|
@ -84,6 +84,7 @@ from lxml import etree
|
|||
from matplotlib.backends.backend_agg import FigureCanvasAgg
|
||||
#from matplotlib.backends.backend_cairo import FigureCanvasCairo as FigureCanvasAgg
|
||||
from matplotlib.figure import Figure
|
||||
from matplotlib import pyplot as plt
|
||||
from terminaltables import AsciiTable
|
||||
|
||||
import msspec
|
||||
|
@ -336,6 +337,15 @@ class DataSet(object):
|
|||
except:
|
||||
pass
|
||||
|
||||
def get_views(self):
|
||||
"""Returns all the defined views in the dataset.
|
||||
|
||||
:return: A list of view
|
||||
:rtype: List of :py:class:`iodata._DataSetView`
|
||||
"""
|
||||
return self._views
|
||||
|
||||
@property
|
||||
def views(self):
|
||||
"""Returns all the defined views in the dataset.
|
||||
|
||||
|
@ -365,7 +375,13 @@ class DataSet(object):
|
|||
mydset.add_parameter(name='Spectrometer', group='misc', value='Omicron', unit='')
|
||||
|
||||
"""
|
||||
self._parameters.append(kwargs)
|
||||
group = kwargs.get('group')
|
||||
name = kwargs.get('name')
|
||||
r = self.get_parameter(group=group, name=name)
|
||||
if r:
|
||||
r.update(**kwargs)
|
||||
else:
|
||||
self._parameters.append(kwargs)
|
||||
|
||||
def parameters(self):
|
||||
"""
|
||||
|
@ -398,30 +414,39 @@ class DataSet(object):
|
|||
p.append(_)
|
||||
return p[0] if len(p) == 1 else p
|
||||
|
||||
def set_cluster(self, cluster):
|
||||
clusbuf = StringIO()
|
||||
cluster.info['absorber'] = cluster.absorber
|
||||
write_xyz(clusbuf, cluster)
|
||||
self.add_parameter(group='Cluster', name='cluster', value=clusbuf.getvalue(), hidden="True")
|
||||
|
||||
def get_cluster(self):
|
||||
"""Get all the atoms in the cluster.
|
||||
|
||||
:return: The cluster
|
||||
:rtype: :py:class:`ase.Atoms`
|
||||
"""
|
||||
p = self.get_parameter(group='Cluster', name='cluster')['value']
|
||||
s = StringIO()
|
||||
s.write(self.get_parameter(group='Cluster', name='cluster')['value'])
|
||||
s.seek(0)
|
||||
#return ase.io.read(s, format='xyz')
|
||||
cluster = list(read_xyz(s))[-1]
|
||||
return cluster
|
||||
try:
|
||||
p = self.get_parameter(group='Cluster', name='cluster')['value']
|
||||
s = StringIO()
|
||||
s.write(self.get_parameter(group='Cluster', name='cluster')['value'])
|
||||
s.seek(0)
|
||||
#return ase.io.read(s, format='xyz')
|
||||
cluster = list(read_xyz(s))[-1]
|
||||
return cluster
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def select(self, *args, **kwargs):
|
||||
condition = kwargs.get('where', 'True')
|
||||
indices = []
|
||||
|
||||
def export_views(self, folder):
|
||||
for view in self.views():
|
||||
def export_views(self, folder, dpi=100):
|
||||
for view in self.get_views():
|
||||
f = view.get_figure()
|
||||
fname = os.path.join(folder, view.title) + '.png'
|
||||
f.savefig(fname)
|
||||
f.savefig(fname, dpi=dpi)
|
||||
|
||||
|
||||
def export(self, filename="", mode="w"):
|
||||
|
@ -671,6 +696,7 @@ class Data(object):
|
|||
return
|
||||
else:
|
||||
data_grp = fd.create_group('DATA')
|
||||
data_grp.attrs['dset_names'] = titles
|
||||
meta_grp = fd.create_group('MsSpec viewer metainfo')
|
||||
|
||||
data_grp.attrs['title'] = self.title
|
||||
|
@ -681,6 +707,7 @@ class Data(object):
|
|||
continue
|
||||
grp = data_grp.create_group(dset.title)
|
||||
grp.attrs['notes'] = dset.notes
|
||||
grp.attrs['col_names'] = dset.columns()
|
||||
for col_name in dset.columns():
|
||||
data = dset[col_name]
|
||||
grp.create_dataset(col_name, data=data)
|
||||
|
@ -691,7 +718,7 @@ class Data(object):
|
|||
# xmlize views
|
||||
for dset in self._datasets:
|
||||
views_node = etree.SubElement(root, 'views', dataset=dset.title)
|
||||
for view in dset.views():
|
||||
for view in dset.get_views():
|
||||
view_el = etree.fromstring(view.to_xml())
|
||||
views_node.append(view_el)
|
||||
|
||||
|
@ -712,7 +739,7 @@ class Data(object):
|
|||
self._dirty = False
|
||||
LOGGER.info('Data saved in {}'.format(os.path.abspath(filename)))
|
||||
|
||||
def export(self, folder, overwrite=False):
|
||||
def export(self, folder, overwrite=False, dpi=150):
|
||||
os.makedirs(folder, exist_ok=overwrite)
|
||||
for dset in self._datasets:
|
||||
dset_name = dset.title.replace(' ', '_')
|
||||
|
@ -720,7 +747,7 @@ class Data(object):
|
|||
os.makedirs(p, exist_ok=overwrite)
|
||||
fname = os.path.join(p, dset_name) + '.txt'
|
||||
dset.export(fname)
|
||||
dset.export_views(p)
|
||||
dset.export_views(p, dpi=dpi)
|
||||
|
||||
@staticmethod
|
||||
def load(filename):
|
||||
|
@ -737,12 +764,20 @@ class Data(object):
|
|||
views = {}
|
||||
|
||||
output.title = fd['DATA'].attrs['title']
|
||||
for dset_name in fd['DATA'] :
|
||||
try:
|
||||
dset_names = fd['DATA'].attrs['dset_names']
|
||||
except:
|
||||
dset_names = [_ for _ in fd['DATA']]
|
||||
for dset_name in dset_names:
|
||||
parameters[dset_name] = []
|
||||
views[dset_name] = []
|
||||
dset = output.add_dset(dset_name)
|
||||
dset.notes = fd['DATA'][dset_name].attrs['notes']
|
||||
for h5dset in fd['DATA'][dset_name]:
|
||||
try:
|
||||
col_names = fd['DATA'][dset_name].attrs['col_names']
|
||||
except:
|
||||
col_names = [_ for _ in fd['DATA'][dset_name]]
|
||||
for h5dset in col_names:
|
||||
dset.add_columns(**{h5dset: fd['DATA'][dset_name][h5dset][...]})
|
||||
|
||||
try:
|
||||
|
@ -870,10 +905,19 @@ class _DataSetView(object):
|
|||
data.append(values)
|
||||
return data
|
||||
|
||||
def get_figure(self):
|
||||
def plot(self):
|
||||
f = self.get_figure(backend='plt')
|
||||
return f, f.get_axes()[0]
|
||||
|
||||
|
||||
def get_figure(self, backend=None):
|
||||
opts = self._plotopts
|
||||
|
||||
figure = Figure(figsize=(3,2))
|
||||
if backend is None:
|
||||
figure = Figure()
|
||||
else:
|
||||
figure = plt.figure(num="[{}][{}]".format(self.dataset.title, self.title))
|
||||
|
||||
axes = None
|
||||
proj = opts['projection']
|
||||
scale = opts['scale']
|
||||
|
@ -1113,7 +1157,7 @@ if has_gui:
|
|||
self.notebooks[dset.title] = nb
|
||||
#self.GetSizer().Add(nb, 1, wx.ALL|wx.EXPAND)
|
||||
self.GetSizer().Add(nb, proportion=1, flag=wx.ALL|wx.EXPAND)
|
||||
for view in dset.views():
|
||||
for view in dset.get_views():
|
||||
self.create_page(nb, view)
|
||||
|
||||
self.create_menu()
|
||||
|
@ -1291,6 +1335,10 @@ if has_gui:
|
|||
self.Layout()
|
||||
self.update_statusbar()
|
||||
self._current_dset = name
|
||||
has_cluster = True if self.data[self._current_dset].get_cluster() is not None else False
|
||||
menu_item = self.GetMenuBar().FindItemById(302)
|
||||
menu_item.Enable(has_cluster)
|
||||
|
||||
|
||||
def create_page(self, nb, view):
|
||||
# Get the matplotlib figure
|
||||
|
@ -1324,95 +1372,6 @@ if has_gui:
|
|||
nb.AddPage(p, view.title)
|
||||
canvas.draw()
|
||||
|
||||
|
||||
def OLDcreate_page(self, nb, view):
|
||||
opts = view._plotopts
|
||||
p = wx.Panel(nb, -1)
|
||||
|
||||
figure = Figure()
|
||||
|
||||
axes = None
|
||||
proj = opts['projection']
|
||||
scale = opts['scale']
|
||||
if proj == 'rectilinear':
|
||||
axes = figure.add_subplot(111, projection='rectilinear')
|
||||
elif proj in ('polar', 'ortho', 'stereo'):
|
||||
axes = figure.add_subplot(111, projection='polar')
|
||||
|
||||
canvas = FigureCanvas(p, -1, figure)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
toolbar = NavigationToolbar2WxAgg(canvas)
|
||||
toolbar.Realize()
|
||||
|
||||
sizer.Add(toolbar, 0, wx.ALL|wx.EXPAND)
|
||||
toolbar.update()
|
||||
|
||||
sizer.Add(canvas, 5, wx.ALL|wx.EXPAND)
|
||||
|
||||
p.SetSizer(sizer)
|
||||
p.Fit()
|
||||
p.Show()
|
||||
|
||||
|
||||
for values, label in zip(view.get_data(), opts['legend']):
|
||||
# if we have only one column to plot, select a bar graph
|
||||
if np.shape(values)[0] == 1:
|
||||
xvalues = list(range(len(values[0])))
|
||||
axes.bar(xvalues, values[0], label=label,
|
||||
picker=5)
|
||||
axes.set_xticks(xvalues)
|
||||
else:
|
||||
if proj in ('ortho', 'stereo'):
|
||||
theta, phi, Xsec = cols2matrix(*values)
|
||||
theta_ticks = np.arange(0, 91, 15)
|
||||
if proj == 'ortho':
|
||||
R = np.sin(np.radians(theta))
|
||||
R_ticks = np.sin(np.radians(theta_ticks))
|
||||
elif proj == 'stereo':
|
||||
R = 2 * np.tan(np.radians(theta/2.))
|
||||
R_ticks = 2 * np.tan(np.radians(theta_ticks/2.))
|
||||
#R = np.tan(np.radians(theta/2.))
|
||||
X, Y = np.meshgrid(np.radians(phi), R)
|
||||
im = axes.pcolormesh(X, Y, Xsec)
|
||||
axes.set_yticks(R_ticks)
|
||||
axes.set_yticklabels(theta_ticks)
|
||||
|
||||
figure.colorbar(im)
|
||||
|
||||
elif proj == 'polar':
|
||||
values[0] = np.radians(values[0])
|
||||
axes.plot(*values, label=label, picker=5,
|
||||
marker=opts['marker'])
|
||||
else:
|
||||
if scale == 'semilogx':
|
||||
pltcmd = axes.semilogx
|
||||
elif scale == 'semilogy':
|
||||
pltcmd = axes.semilogy
|
||||
elif scale == 'log':
|
||||
pltcmd = axes.loglog
|
||||
else:
|
||||
pltcmd = axes.plot
|
||||
pltcmd(*values, label=label, picker=5,
|
||||
marker=opts['marker'])
|
||||
axes.grid(opts['grid'])
|
||||
axes.set_title(opts['title'])
|
||||
axes.set_xlabel(opts['xlabel'])
|
||||
axes.set_ylabel(opts['ylabel'])
|
||||
axes.set_xlim(*opts['xlim'])
|
||||
axes.set_ylim(*opts['ylim'])
|
||||
if label:
|
||||
axes.legend()
|
||||
axes.autoscale(enable=opts['autoscale'])
|
||||
|
||||
|
||||
# MPL events
|
||||
figure.canvas.mpl_connect('motion_notify_event', self.on_mpl_motion)
|
||||
figure.canvas.mpl_connect('pick_event', self.on_mpl_pick)
|
||||
|
||||
nb.AddPage(p, view.title)
|
||||
|
||||
|
||||
def update_statusbar(self):
|
||||
sb = self.GetStatusBar()
|
||||
menu_id = self.GetMenuBar().FindMenu('Datasets')
|
||||
|
|
Loading…
Reference in New Issue