pypsbuilder 2.4.1__tar.gz → 2.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/CHANGELOG.md +8 -2
  2. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/PKG-INFO +10 -4
  3. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/conf.py +2 -2
  4. pypsbuilder-2.5.0/pyproject.toml +50 -0
  5. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/__init__.py +2 -2
  6. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/psbuilders.py +3 -3
  7. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/psclasses.py +33 -20
  8. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/psexplorer.py +72 -33
  9. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder.egg-info/PKG-INFO +10 -4
  10. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder.egg-info/SOURCES.txt +1 -0
  11. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/setup.cfg +3 -1
  12. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/setup.py +2 -2
  13. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/AUTHORS.md +0 -0
  14. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/CONTRIBUTING.md +0 -0
  15. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/LICENSE +0 -0
  16. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/MANIFEST.in +0 -0
  17. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/README.md +0 -0
  18. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/Makefile +0 -0
  19. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/api/pypsbuilder.psclasses.Dogmin.rst +0 -0
  20. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/api/pypsbuilder.psclasses.InvPoint.rst +0 -0
  21. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/api/pypsbuilder.psclasses.PTsection.rst +0 -0
  22. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/api/pypsbuilder.psclasses.PXsection.rst +0 -0
  23. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/api/pypsbuilder.psclasses.TCResult.rst +0 -0
  24. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/api/pypsbuilder.psclasses.TCResultSet.rst +0 -0
  25. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/api/pypsbuilder.psclasses.TXsection.rst +0 -0
  26. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/api/pypsbuilder.psclasses.UniLine.rst +0 -0
  27. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/api/pypsbuilder.psexplorer.PTPS.rst +0 -0
  28. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/api/pypsbuilder.psexplorer.PXPS.rst +0 -0
  29. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/api/pypsbuilder.psexplorer.TXPS.rst +0 -0
  30. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/api/pypsbuilder.tcapi.TC34API.rst +0 -0
  31. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/api/pypsbuilder.tcapi.TC35API.rst +0 -0
  32. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/api.rst +0 -0
  33. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/authors.rst +0 -0
  34. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/command-line.rst +0 -0
  35. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/index.rst +0 -0
  36. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/installation.rst +0 -0
  37. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/psbuilders-tutorial.rst +0 -0
  38. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/docs/psexplorer-tutorial.rst +0 -0
  39. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/images/__init__.py +0 -0
  40. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/images/ptbuilder.png +0 -0
  41. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/images/pxbuilder.png +0 -0
  42. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/images/pypsbuilder.png +0 -0
  43. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/images/txbuilder.png +0 -0
  44. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/tcapi.py +0 -0
  45. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/tcinit.py +0 -0
  46. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/tests/__init__.py +0 -0
  47. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/tests/test_pclasses.py +0 -0
  48. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/ui_addinv.py +0 -0
  49. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/ui_adduni.py +0 -0
  50. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/ui_ptbuilder.py +0 -0
  51. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/ui_pxbuilder.py +0 -0
  52. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/ui_txbuilder.py +0 -0
  53. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder/ui_uniguess.py +0 -0
  54. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder.egg-info/dependency_links.txt +0 -0
  55. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder.egg-info/entry_points.txt +0 -0
  56. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder.egg-info/not-zip-safe +0 -0
  57. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder.egg-info/requires.txt +0 -0
  58. {pypsbuilder-2.4.1 → pypsbuilder-2.5.0}/pypsbuilder.egg-info/top_level.txt +0 -0
@@ -1,7 +1,13 @@
1
1
  # Changelog
2
2
  All notable pypsbuilder changes.
3
3
 
4
- ## master
4
+ ## [2.5.0] - 2024-12-13
5
+ ### Fixed
6
+ - fix for coe-q
7
+
8
+ ## [2.4.2] - 2024-04-23
9
+ ### Fixed
10
+ - another fix of and-ky-sill triple point linking
5
11
 
6
12
  ## [2.4.1] - 2024-03-07
7
13
  ### Fixed
@@ -58,7 +64,7 @@ All notable pypsbuilder changes.
58
64
  - latest THERMOCALC 3.50 compatibility
59
65
 
60
66
  ### Added
61
- - isopleths quadratic surface fit method added
67
+ - isopleths quadratic surface fit method added
62
68
  - isopleths figure and savefig options added
63
69
 
64
70
  ## [2.2.2] - 2021-01-25
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pypsbuilder
3
- Version: 2.4.1
3
+ Version: 2.5.0
4
4
  Summary: THERMOCALC front-end for constructing and analyzing PT pseudosections
5
5
  Home-page: https://github.com/ondrolexa/pypsbuilder
6
6
  Author: Ondrej Lexa
@@ -13,7 +13,7 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
13
13
  Classifier: Programming Language :: Python :: 3 :: Only
14
14
  Classifier: Topic :: Scientific/Engineering
15
15
  Classifier: Topic :: Utilities
16
- Requires-Python: >=3.8
16
+ Requires-Python: >=3.9
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
19
  License-File: AUTHORS.md
@@ -88,7 +88,13 @@ pypsbuilder is free software: you can redistribute it and/or modify it under the
88
88
  # Changelog
89
89
  All notable pypsbuilder changes.
90
90
 
91
- ## master
91
+ ## [2.5.0] - 2024-12-13
92
+ ### Fixed
93
+ - fix for coe-q
94
+
95
+ ## [2.4.2] - 2024-04-23
96
+ ### Fixed
97
+ - another fix of and-ky-sill triple point linking
92
98
 
93
99
  ## [2.4.1] - 2024-03-07
94
100
  ### Fixed
@@ -145,7 +151,7 @@ All notable pypsbuilder changes.
145
151
  - latest THERMOCALC 3.50 compatibility
146
152
 
147
153
  ### Added
148
- - isopleths quadratic surface fit method added
154
+ - isopleths quadratic surface fit method added
149
155
  - isopleths figure and savefig options added
150
156
 
151
157
  ## [2.2.2] - 2021-01-25
@@ -75,9 +75,9 @@ author = "Ondrej Lexa"
75
75
  # built documents.
76
76
  #
77
77
  # The short X.Y version.
78
- version = "2.4"
78
+ version = "2.5"
79
79
  # The full version, including alpha/beta/rc tags.
80
- release = "2.4.1"
80
+ release = "2.5.0"
81
81
 
82
82
  # The language for content autogenerated by Sphinx. Refer to documentation
83
83
  # for a list of supported languages.
@@ -0,0 +1,50 @@
1
+ [tool.poetry]
2
+ name = "pypsbuilder"
3
+ version = "2.5.0"
4
+ description = "THERMOCALC front-end for constructing and analyzing PT pseudosections"
5
+ authors = ["Ondrej Lexa <lexa.ondrej@gmail.com>"]
6
+ readme = "README.md"
7
+
8
+ [tool.poetry.dependencies]
9
+ python = "^3.9"
10
+ numpy = "^1.20"
11
+ matplotlib = "^3.6"
12
+ pyqt5 = "^5.15"
13
+ scipy = "^1.10"
14
+ networkx = "^3.2"
15
+ shapely = "^2.0"
16
+ tqdm = "^4.0"
17
+
18
+ [tool.poetry.group.test.dependencies]
19
+ pytest = "^7.4"
20
+ black = "^24"
21
+
22
+ [tool.poetry.scripts]
23
+ ptbuilder = "pypsbuilder.psbuilders:ptbuilder"
24
+ txbuilder = "pypsbuilder.psbuilders:txbuilder"
25
+ pxbuilder = "pypsbuilder.psbuilders:pxbuilder"
26
+ psshow = "pypsbuilder.psexplorer:ps_show"
27
+ psiso = "pypsbuilder.psexplorer:ps_iso"
28
+ psgrid = "pypsbuilder.psexplorer:ps_grid"
29
+ psdrawpd = "pypsbuilder.psexplorer:ps_drawpd"
30
+ tcinit = "pypsbuilder.tcinit:tcprojinit"
31
+
32
+ [build-system]
33
+ requires = ["poetry-core"]
34
+ build-backend = "poetry.core.masonry.api"
35
+
36
+ [tool.black]
37
+ line-length = 88
38
+ include = '\.pyi?$'
39
+ exclude = '''
40
+ /(
41
+ \.toml
42
+ |\.sh
43
+ |\.git
44
+ |\.ini
45
+ )/
46
+ '''
47
+
48
+ [[tool.poetry.source]]
49
+ name = "pypi-public"
50
+ url = "https://pypi.org/simple/"
@@ -22,7 +22,7 @@ __all__ = (
22
22
  "get_tcapi",
23
23
  )
24
24
 
25
- __version__ = "2.4.1"
25
+ __version__ = "2.5.0"
26
26
  __author__ = "Ondrej Lexa"
27
- __copyright__ = "© Ondrej Lexa 2024"
27
+ __copyright__ = "© Ondrej Lexa 2016-2024"
28
28
  __email__ = "lexa.ondrej@gmail.com"
@@ -14,7 +14,7 @@ from pathlib import Path
14
14
  from datetime import datetime
15
15
  import itertools
16
16
 
17
- from pkg_resources import resource_filename
17
+ import importlib.resources as ires
18
18
  from PyQt5 import QtCore, QtGui, QtWidgets
19
19
  from PyQt5.QtCore import QT_VERSION_STR
20
20
  from PyQt5.Qt import PYQT_VERSION_STR
@@ -94,7 +94,7 @@ class BuildersBase(QtWidgets.QMainWindow):
94
94
  res = QtWidgets.QDesktopWidget().screenGeometry()
95
95
  self.resize(min(1280, res.width() - 10), min(720, res.height() - 10))
96
96
  self.setWindowTitle(self.builder_name)
97
- window_icon = resource_filename("pypsbuilder", app_icons[self.builder_name])
97
+ window_icon = str(ires.files("pypsbuilder").joinpath(app_icons[self.builder_name]))
98
98
  self.setWindowIcon(QtGui.QIcon(window_icon))
99
99
  self.__changed = False
100
100
  self.about_dialog = AboutDialog(self.builder_name, __version__, __copyright__)
@@ -5097,7 +5097,7 @@ class TopologyGraph(QtWidgets.QDialog):
5097
5097
  def __init__(self, ps, parent=None):
5098
5098
  super(TopologyGraph, self).__init__(parent)
5099
5099
  self.setWindowTitle("Topology graph")
5100
- window_icon = resource_filename("pypsbuilder", "images/pypsbuilder.png")
5100
+ window_icon = str(ires.files("pypsbuilder").joinpath("images/pypsbuilder.png"))
5101
5101
  self.setWindowIcon(QtGui.QIcon(window_icon))
5102
5102
  self.setWindowFlags(
5103
5103
  QtCore.Qt.WindowMinMaxButtonsHint | QtCore.Qt.WindowCloseButtonHint
@@ -4,6 +4,7 @@ This module contains classes and tools providing API to THERMOCALC, parsing of
4
4
  outputs and storage of calculated invariant points and univariant lines.
5
5
 
6
6
  """
7
+
7
8
  # author: Ondrej Lexa
8
9
  # website: https://github.com/ondrolexa/pypsbuilder
9
10
 
@@ -282,8 +283,8 @@ class UniLine(PseudoBase):
282
283
  return candidate
283
284
 
284
285
  # Check for polymorphs
285
- fixi, fixu = False, False
286
286
  for poly in polymorphs:
287
+ fixi, fixu = False, False
287
288
  if (
288
289
  poly.issubset(ip.phases)
289
290
  and (poly != ip.out)
@@ -292,20 +293,21 @@ class UniLine(PseudoBase):
292
293
  fixi = True
293
294
  if poly.issubset(self.phases) and not self.out.isdisjoint(poly):
294
295
  fixu = True
296
+ # check invs
297
+ candidate = checkme(self.phases, self.out, ip.phases, ip.out)
298
+ if fixi and not candidate:
299
+ candidate = checkme(
300
+ self.phases,
301
+ self.out,
302
+ ip.phases,
303
+ ip.out.difference(poly).union(poly.difference(ip.out)),
304
+ )
305
+ if fixu and not candidate:
306
+ candidate = checkme(
307
+ self.phases, poly.difference(self.out), ip.phases, ip.out
308
+ )
309
+ if candidate:
295
310
  break
296
- # check invs
297
- candidate = checkme(self.phases, self.out, ip.phases, ip.out)
298
- if fixi and not candidate:
299
- candidate = checkme(
300
- self.phases,
301
- self.out,
302
- ip.phases,
303
- ip.out.difference(poly).union(poly.difference(ip.out)),
304
- )
305
- if fixu and not candidate:
306
- candidate = checkme(
307
- self.phases, poly.difference(self.out), ip.phases, ip.out
308
- )
309
311
  return candidate
310
312
 
311
313
  def get_label_point(self):
@@ -472,9 +474,11 @@ class TCResult:
472
474
  phases = head.split()[1:]
473
475
  # fixed width parsing !!!
474
476
  valsf = [
475
- float(vals[6:][12 * i : 12 * (i + 1)].strip())
476
- if vals[6:][12 * i : 12 * (i + 1)].strip() != ""
477
- else 0.0
477
+ (
478
+ float(vals[6:][12 * i : 12 * (i + 1)].strip())
479
+ if vals[6:][12 * i : 12 * (i + 1)].strip() != ""
480
+ else 0.0
481
+ )
478
482
  for i in range(len(phases))
479
483
  ]
480
484
  for phase, val in zip(phases, valsf):
@@ -483,9 +487,11 @@ class TCResult:
483
487
  head, vals = factor.split("\n")
484
488
  phases = head.split()[1:]
485
489
  valsf = [
486
- float(vals[6:][12 * i : 12 * (i + 1)].strip())
487
- if vals[6:][12 * i : 12 * (i + 1)].strip() != ""
488
- else 0.0
490
+ (
491
+ float(vals[6:][12 * i : 12 * (i + 1)].strip())
492
+ if vals[6:][12 * i : 12 * (i + 1)].strip() != ""
493
+ else 0.0
494
+ )
489
495
  for i in range(len(phases))
490
496
  ]
491
497
  for phase, val in zip(phases, valsf):
@@ -933,6 +939,13 @@ class SectionBase:
933
939
  phases = self.unilines[unilist[0]].phases.difference(
934
940
  self.unilines[unilist[0]].out
935
941
  )
942
+ if frozenset(phases) in shapes: # switch polymorph
943
+ for pp in polymorphs:
944
+ if self.unilines[unilist[0]].out.issubset(pp):
945
+ phases = self.unilines[unilist[0]].phases.difference(
946
+ pp.difference(self.unilines[unilist[0]].out)
947
+ )
948
+ break
936
949
  shapes[frozenset(phases)] = poly
937
950
  unilists[frozenset(phases)] = unilist
938
951
  elif frozenset(phases) in shapes:
@@ -636,12 +636,13 @@ class PS:
636
636
  mn, mx = sys.float_info.max, -sys.float_info.max
637
637
  recs = OrderedDict()
638
638
  for key in self:
639
- d = self.collect_data(key, phase, expr, which=which)
640
- z = d["data"]
641
- if z:
642
- recs[key] = d
643
- mn = min(mn, min(z))
644
- mx = max(mx, max(z))
639
+ if phase.split('(')[0] in key:
640
+ d = self.collect_data(key, phase, expr, which=which)
641
+ z = d["data"]
642
+ if z:
643
+ recs[key] = d
644
+ mn = min(mn, min(z))
645
+ mx = max(mx, max(z))
645
646
  # res = self.grid.gridcalcs[self.grid.masks[key]]
646
647
  # if len(res) > 0:
647
648
  # if phase in res[0]['data']:
@@ -948,7 +949,7 @@ class PS:
948
949
  cgd = {}
949
950
  mn, mx = sys.float_info.max, -sys.float_info.max
950
951
  for ix, grid in self.grids.items():
951
- gd = np.empty(grid.xg.shape)
952
+ gd = np.empty(grid.xg.shape, dtype=float)
952
953
  gd[:] = np.nan
953
954
  for key in grid.masks:
954
955
  results = grid.gridcalcs[grid.masks[key] & (grid.status == 1)]
@@ -989,9 +990,12 @@ class PS:
989
990
  self,
990
991
  *args,
991
992
  interpolation=None,
993
+ colors=None,
992
994
  label=False,
993
995
  skiplabels=0,
994
996
  labelfs=6,
997
+ logerr=True,
998
+ maxerr=10,
995
999
  geterror=False,
996
1000
  getpt=False,
997
1001
  fig=None,
@@ -999,6 +1003,10 @@ class PS:
999
1003
  isopleths=False,
1000
1004
  which=7,
1001
1005
  smooth=0,
1006
+ alpha=0.5,
1007
+ lw=2,
1008
+ filename=None,
1009
+ save_kw={},
1002
1010
  ):
1003
1011
  """Function to plot root squared error of calculated and estimated values.
1004
1012
 
@@ -1011,6 +1019,7 @@ class PS:
1011
1019
  interpolation (str): matplotlib imshow interpolation method.
1012
1020
  Default None.
1013
1021
  label (bool): Whether to label divariant fields. Default False.
1022
+ logerr (bool): When True, plot logarithms of error. Default True
1014
1023
  geterror (bool): When True, calculated RMSE array is returned. Otherwise
1015
1024
  error is plotted. Deafult False
1016
1025
  getpt (bool): When True return tuple of (p, T, err) where error is minimal.
@@ -1020,7 +1029,9 @@ class PS:
1020
1029
  fig (Figure): If not None, axes are added to fig and returned.
1021
1030
  Default None
1022
1031
  fig_kw: dict passed to subplots method.
1023
- isopleths (bool): When True, searched isoplots are shown.Default False
1032
+ filename: If not None, figure is saved to file
1033
+ save_kw: dict passed to savefig method.
1034
+ isopleths (bool): When True, searched isopleths are shown. Default False
1024
1035
  which (int): Bitopt defining from where data are collected. 0 bit -
1025
1036
  invariant points, 1 bit - uniariant lines and 2 bit - GridData
1026
1037
  points
@@ -1036,6 +1047,8 @@ class PS:
1036
1047
  if len(args) % 3 == 0:
1037
1048
  if self.gridded:
1038
1049
  err = []
1050
+ if colors is None:
1051
+ colors = list(mcolors.TABLEAU_COLORS.keys())[: len(args) // 3]
1039
1052
  for phase, expr, val in zip(args[::3], args[1::3], args[2::3]):
1040
1053
  if self.check_phase_expr(phase, expr):
1041
1054
  err.append(
@@ -1049,6 +1062,7 @@ class PS:
1049
1062
  )
1050
1063
 
1051
1064
  err = np.sqrt(sum(err)) / len(err)
1065
+ err[err > maxerr] = np.nan
1052
1066
  r, c = np.unravel_index(np.nanargmin(err), err.shape)
1053
1067
  p = self.yspace[r]
1054
1068
  T = self.xspace[c]
@@ -1068,13 +1082,22 @@ class PS:
1068
1082
  interpolation=interpolation,
1069
1083
  aspect="auto",
1070
1084
  origin="lower",
1085
+ alpha=alpha,
1071
1086
  )
1072
- ax.contour(self.xspace, self.yspace, err, colors="w")
1087
+ if logerr:
1088
+ ax.contour(self.xspace, self.yspace, np.log(err), colors="w")
1089
+ else:
1090
+ ax.contour(self.xspace, self.yspace, err, colors="w")
1073
1091
  if isopleths:
1074
- for phase, expr, val in zip(args[::3], args[1::3], args[2::3]):
1092
+ for phase, expr, val, cc in zip(
1093
+ args[::3],
1094
+ args[1::3],
1095
+ args[2::3],
1096
+ colors,
1097
+ ):
1075
1098
  if self.check_phase_expr(phase, expr):
1076
1099
  ax = self.isopleths_vector(
1077
- phase, expr, levels=[val], ax=ax
1100
+ phase, expr, levels=[val], ax=ax, lw=lw, color=cc
1078
1101
  )
1079
1102
  ax.plot(T, p, "r*", ms=20)
1080
1103
  self.add_overlay(
@@ -1084,9 +1107,14 @@ class PS:
1084
1107
  ax.set_ylim(self.yrange)
1085
1108
  fig.colorbar(im)
1086
1109
 
1087
- ax.set_title(f"RMSE - MinErr={minerr:g} at {T} {p}")
1110
+ ax.set_title(f"RMSE - MinErr={minerr:g} at {T:g} {p:g}")
1088
1111
  fig.tight_layout()
1089
- plt.show()
1112
+
1113
+ if filename is not None:
1114
+ plt.savefig(filename, **save_kw)
1115
+ plt.close(fig)
1116
+ else:
1117
+ plt.show()
1090
1118
  else:
1091
1119
  print("Not yet gridded...")
1092
1120
  else:
@@ -1714,10 +1742,10 @@ class PS:
1714
1742
  table(ax=ax, cellText=[val1, val2], colLabels=ox, loc="top")
1715
1743
  else:
1716
1744
  if only is None:
1717
- if show is None or show is True:
1718
- ax.set_xlim(self.xrange)
1719
- ax.set_ylim(self.yrange)
1720
- ax.set_title("{}({})".format(phase, expr))
1745
+ # if show is None or show is True:
1746
+ ax.set_xlim(self.xrange)
1747
+ ax.set_ylim(self.yrange)
1748
+ ax.set_title("{}({})".format(phase, expr))
1721
1749
  else:
1722
1750
  ax.set_title("{} - {}({})".format(" ".join(only), phase, expr))
1723
1751
  # coords
@@ -1746,13 +1774,17 @@ class PS:
1746
1774
  fig (Figure): If not None, axes are added to fig and returned.
1747
1775
  Default None
1748
1776
  fig_kw: dict passed to subplots method.
1777
+ filename: If not None, figure is saved to file
1778
+ save_kw: dict passed to savefig method.
1779
+ show (bool): When False, Axes are returned, otherwise plot is shown.
1780
+ Default True
1749
1781
 
1750
1782
  Example:
1751
1783
  >>> pt.overlap_isopleths(
1752
- 'g', 'xMgX', (0.07, 0.13),
1753
1784
  'g', 'xFeX', (0.51, 0.65),
1754
- 'g', 'xCaX', (0.06, 0.15),
1785
+ 'g', 'xMgX', (0.07, 0.13),
1755
1786
  'g', 'xMnX', (0.16, 0.27),
1787
+ 'g', 'xCaX', (0.06, 0.15),
1756
1788
  )
1757
1789
  """
1758
1790
  if len(args) % 3 == 0:
@@ -1766,10 +1798,7 @@ class PS:
1766
1798
  show = kwargs.get("show", None)
1767
1799
  colors = kwargs.get("colors", None)
1768
1800
  if colors is None:
1769
- cc = list(mcolors.TABLEAU_COLORS.keys())
1770
- cixs = np.random.choice(
1771
- range(len(cc)), size=len(args) // 3, replace=False
1772
- )
1801
+ colors = list(mcolors.TABLEAU_COLORS.keys())[: len(args) // 3]
1773
1802
  handles = []
1774
1803
  if fig is None:
1775
1804
  if ax is None:
@@ -1783,7 +1812,7 @@ class PS:
1783
1812
  show = False
1784
1813
  ax = fig.add_subplot()
1785
1814
  for phase, expr, levels, color in zip(
1786
- args[::3], args[1::3], args[2::3], cixs
1815
+ args[::3], args[1::3], args[2::3], colors
1787
1816
  ):
1788
1817
  ax = self.isopleths(
1789
1818
  phase,
@@ -1791,20 +1820,19 @@ class PS:
1791
1820
  levels=levels,
1792
1821
  colorbar=False,
1793
1822
  filled_over=True,
1794
- colors=[cc[color]],
1823
+ colors=[color],
1795
1824
  alpha=alpha,
1796
1825
  show=False,
1797
1826
  ax=ax,
1798
1827
  )
1799
- handles.append(
1800
- mpatches.Patch(color=cc[color], alpha=alpha, label=expr)
1801
- )
1828
+ handles.append(mpatches.Patch(color=color, alpha=alpha, label=expr))
1802
1829
  self.add_overlay(ax)
1803
1830
  ax.legend(handles=handles)
1804
1831
  # coords
1805
1832
  ax.format_coord = self.format_coord
1806
1833
  # connect button press
1807
1834
  # cid = fig.canvas.mpl_connect('button_press_event', self.onclick)
1835
+ ax.set_title(self.name)
1808
1836
  if filename is not None:
1809
1837
  plt.savefig(filename, **save_kw)
1810
1838
  plt.close(fig)
@@ -1858,16 +1886,17 @@ class PS:
1858
1886
  overlay (bool): Whether to show assemblage fields. Default True
1859
1887
  high (frozenset or list): Highlight divariant fields identified
1860
1888
  by key(s).
1861
- cmap (str): matplotlib colormap used to divariant fields coloring.
1862
- Colors are based on variance. Default 'viridis'.
1889
+ cmap (str): matplotlib colormap used isopleths coloring. Default 'viridis'.
1863
1890
  bulk (bool): Whether to show bulk composition on top of diagram.
1864
1891
  Default False.
1865
1892
  fig (Figure): If not None, axes are added to fig and returned.
1866
1893
  Default None
1867
1894
  fig_kw: dict passed to subplots method.
1895
+ lw (float): Linewidth of isopleths. Default 1.0
1868
1896
  ax (Axes): Axes to be used. Default None
1869
1897
  filename: If not None, figure is saved to file
1870
1898
  save_kw: dict passed to savefig method.
1899
+ color: matplotlib color for isopleths. If None cmap is used. Default None.
1871
1900
  show (bool): When False, Axes are returned, otherwise plot is shown.
1872
1901
  Default True
1873
1902
  """
@@ -1893,9 +1922,11 @@ class PS:
1893
1922
  method = kwargs.get("method", "rbf")
1894
1923
  rbf_func = kwargs.get("rbf_func", "thin_plate")
1895
1924
  cmap = kwargs.get("cmap", "viridis")
1925
+ color = kwargs.get("color", None)
1896
1926
  colorbar = kwargs.get("colorbar", True)
1897
1927
  fig = kwargs.get("fig", None)
1898
1928
  fig_kw = kwargs.get("fig_kw", {})
1929
+ lw = kwargs.get("lw", 1.0)
1899
1930
  ax = kwargs.get("ax", None)
1900
1931
  filename = kwargs.get("filename", None)
1901
1932
  save_kw = kwargs.get("save_kw", {})
@@ -2085,11 +2116,19 @@ class PS:
2085
2116
  for lnp in ln.geoms:
2086
2117
  lnp = lnp.simplify(tolerance=0.01)
2087
2118
  x, y = np.array(lnp.coords).T
2088
- ax.plot(x, y, color=mapper.to_rgba(v))
2119
+ if color is None:
2120
+ ax.plot(
2121
+ x, y, color=mapper.to_rgba(v), lw=lw
2122
+ )
2123
+ else:
2124
+ ax.plot(x, y, color=color, lw=lw)
2089
2125
  else:
2090
2126
  ln = ln.simplify(tolerance=0.01)
2091
2127
  x, y = np.array(ln.coords).T
2092
- ax.plot(x, y, color=mapper.to_rgba(v))
2128
+ if color is None:
2129
+ ax.plot(x, y, color=mapper.to_rgba(v), lw=lw)
2130
+ else:
2131
+ ax.plot(x, y, color=color, lw=lw)
2093
2132
  if only is None:
2094
2133
  if overlay:
2095
2134
  self.add_overlay(ax)
@@ -2357,7 +2396,7 @@ class PS:
2357
2396
  self.common_grid_and_masks()
2358
2397
  # interpolate on common grid
2359
2398
  recs, mn, mx = self.merge_data(phase, expr, which=which)
2360
- gd = np.empty(self.xg.shape)
2399
+ gd = np.empty(self.xg.shape, dtype=float)
2361
2400
  gd[:] = np.nan
2362
2401
  for key in recs:
2363
2402
  xmin, ymin, xmax, ymax = self.shapes[key].bounds
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pypsbuilder
3
- Version: 2.4.1
3
+ Version: 2.5.0
4
4
  Summary: THERMOCALC front-end for constructing and analyzing PT pseudosections
5
5
  Home-page: https://github.com/ondrolexa/pypsbuilder
6
6
  Author: Ondrej Lexa
@@ -13,7 +13,7 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
13
13
  Classifier: Programming Language :: Python :: 3 :: Only
14
14
  Classifier: Topic :: Scientific/Engineering
15
15
  Classifier: Topic :: Utilities
16
- Requires-Python: >=3.8
16
+ Requires-Python: >=3.9
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
19
  License-File: AUTHORS.md
@@ -88,7 +88,13 @@ pypsbuilder is free software: you can redistribute it and/or modify it under the
88
88
  # Changelog
89
89
  All notable pypsbuilder changes.
90
90
 
91
- ## master
91
+ ## [2.5.0] - 2024-12-13
92
+ ### Fixed
93
+ - fix for coe-q
94
+
95
+ ## [2.4.2] - 2024-04-23
96
+ ### Fixed
97
+ - another fix of and-ky-sill triple point linking
92
98
 
93
99
  ## [2.4.1] - 2024-03-07
94
100
  ### Fixed
@@ -145,7 +151,7 @@ All notable pypsbuilder changes.
145
151
  - latest THERMOCALC 3.50 compatibility
146
152
 
147
153
  ### Added
148
- - isopleths quadratic surface fit method added
154
+ - isopleths quadratic surface fit method added
149
155
  - isopleths figure and savefig options added
150
156
 
151
157
  ## [2.2.2] - 2021-01-25
@@ -4,6 +4,7 @@ CONTRIBUTING.md
4
4
  LICENSE
5
5
  MANIFEST.in
6
6
  README.md
7
+ pyproject.toml
7
8
  setup.cfg
8
9
  setup.py
9
10
  docs/Makefile
@@ -1,11 +1,13 @@
1
1
  [bumpversion]
2
- current_version = 2.4.1
2
+ current_version = 2.5.0
3
3
  commit = True
4
4
  tag = True
5
5
  tag_name = {new_version}
6
6
 
7
7
  [bumpversion:file:setup.py]
8
8
 
9
+ [bumpversion:file:pyproject.toml]
10
+
9
11
  [bumpversion:file:docs/conf.py]
10
12
 
11
13
  [bumpversion:file:pypsbuilder/__init__.py]
@@ -15,7 +15,7 @@ requirements = ["numpy", "matplotlib>=3", "scipy", "networkx", "shapely>=2", "tq
15
15
 
16
16
  setup(
17
17
  name="pypsbuilder",
18
- version="2.4.1",
18
+ version="2.5.0",
19
19
  description="THERMOCALC front-end for constructing and analyzing PT pseudosections",
20
20
  long_description=readme + "\n\n" + changelog,
21
21
  long_description_content_type="text/markdown",
@@ -23,7 +23,7 @@ setup(
23
23
  author_email="lexa.ondrej@gmail.com",
24
24
  url="https://github.com/ondrolexa/pypsbuilder",
25
25
  license="MIT",
26
- python_requires=">=3.8",
26
+ python_requires=">=3.9",
27
27
  packages=find_packages(),
28
28
  package_data={"pypsbuilder.images": ["*.png"]},
29
29
  entry_points="""
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes