sdv 1.34.1.dev0__tar.gz → 1.34.2.dev0__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 (87) hide show
  1. {sdv-1.34.1.dev0/sdv.egg-info → sdv-1.34.2.dev0}/PKG-INFO +1 -1
  2. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/pyproject.toml +1 -1
  3. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/__init__.py +1 -1
  4. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/metadata/multi_table.py +22 -7
  5. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/metadata/single_table.py +20 -6
  6. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/metadata/visualization.py +14 -2
  7. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/multi_table/hma.py +4 -2
  8. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/sampling/hierarchical_sampler.py +9 -1
  9. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0/sdv.egg-info}/PKG-INFO +1 -1
  10. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/LICENSE +0 -0
  11. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/README.md +0 -0
  12. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/_utils.py +0 -0
  13. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/cag/__init__.py +0 -0
  14. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/cag/_errors.py +0 -0
  15. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/cag/_utils.py +0 -0
  16. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/cag/base.py +0 -0
  17. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/cag/fixed_combinations.py +0 -0
  18. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/cag/fixed_increments.py +0 -0
  19. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/cag/inequality.py +0 -0
  20. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/cag/one_hot_encoding.py +0 -0
  21. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/cag/programmable_constraint.py +0 -0
  22. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/cag/range.py +0 -0
  23. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/constraints/__init__.py +0 -0
  24. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/constraints/base.py +0 -0
  25. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/constraints/errors.py +0 -0
  26. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/constraints/tabular.py +0 -0
  27. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/constraints/utils.py +0 -0
  28. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/data_processing/__init__.py +0 -0
  29. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/data_processing/data_processor.py +0 -0
  30. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/data_processing/datetime_formatter.py +0 -0
  31. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/data_processing/errors.py +0 -0
  32. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/data_processing/numerical_formatter.py +0 -0
  33. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/data_processing/utils.py +0 -0
  34. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/datasets/__init__.py +0 -0
  35. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/datasets/demo.py +0 -0
  36. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/datasets/local.py +0 -0
  37. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/errors.py +0 -0
  38. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/evaluation/__init__.py +0 -0
  39. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/evaluation/_utils.py +0 -0
  40. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/evaluation/multi_table.py +0 -0
  41. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/evaluation/single_table.py +0 -0
  42. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/io/__init__.py +0 -0
  43. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/io/local/__init__.py +0 -0
  44. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/io/local/local.py +0 -0
  45. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/lite/__init__.py +0 -0
  46. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/lite/single_table.py +0 -0
  47. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/logging/__init__.py +0 -0
  48. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/logging/logger.py +0 -0
  49. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/logging/sdv_logger_config.yml +0 -0
  50. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/logging/utils.py +0 -0
  51. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/metadata/__init__.py +0 -0
  52. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/metadata/errors.py +0 -0
  53. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/metadata/metadata.py +3 -3
  54. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/metadata/metadata_upgrader.py +0 -0
  55. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/metadata/utils.py +0 -0
  56. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/metrics/__init__.py +0 -0
  57. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/metrics/demos.py +0 -0
  58. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/metrics/relational.py +0 -0
  59. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/metrics/tabular.py +0 -0
  60. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/metrics/timeseries.py +0 -0
  61. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/multi_table/__init__.py +0 -0
  62. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/multi_table/base.py +0 -0
  63. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/multi_table/dayz.py +0 -0
  64. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/multi_table/utils.py +0 -0
  65. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/sampling/__init__.py +0 -0
  66. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/sampling/independent_sampler.py +0 -0
  67. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/sampling/tabular.py +0 -0
  68. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/sequential/__init__.py +0 -0
  69. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/sequential/par.py +0 -0
  70. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/single_table/__init__.py +0 -0
  71. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/single_table/base.py +0 -0
  72. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/single_table/copulagan.py +0 -0
  73. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/single_table/copulas.py +0 -0
  74. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/single_table/ctgan.py +6 -6
  75. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/single_table/dayz.py +0 -0
  76. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/single_table/utils.py +0 -0
  77. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/utils/__init__.py +0 -0
  78. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/utils/mixins.py +0 -0
  79. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/utils/poc.py +0 -0
  80. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/utils/utils.py +0 -0
  81. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv/version/__init__.py +0 -0
  82. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv.egg-info/SOURCES.txt +0 -0
  83. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv.egg-info/dependency_links.txt +0 -0
  84. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv.egg-info/entry_points.txt +0 -0
  85. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv.egg-info/requires.txt +0 -0
  86. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/sdv.egg-info/top_level.txt +0 -0
  87. {sdv-1.34.1.dev0 → sdv-1.34.2.dev0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sdv
3
- Version: 1.34.1.dev0
3
+ Version: 1.34.2.dev0
4
4
  Summary: Generate synthetic data for single table, multi table and sequential data
5
5
  Author-email: "DataCebo, Inc." <info@sdv.dev>
6
6
  License-Expression: BUSL-1.1
@@ -150,7 +150,7 @@ namespaces = false
150
150
  version = {attr = 'sdv.__version__'}
151
151
 
152
152
  [tool.bumpversion]
153
- current_version = "1.34.1.dev0"
153
+ current_version = "1.34.2.dev0"
154
154
  parse = '(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\.(?P<release>[a-z]+)(?P<candidate>\d+))?'
155
155
  serialize = [
156
156
  '{major}.{minor}.{patch}.{release}{candidate}',
@@ -6,7 +6,7 @@
6
6
 
7
7
  __author__ = 'DataCebo, Inc.'
8
8
  __email__ = 'info@sdv.dev'
9
- __version__ = '1.34.1.dev0'
9
+ __version__ = '1.34.2.dev0'
10
10
 
11
11
 
12
12
  import sys
@@ -835,11 +835,14 @@ class MultiTableMetadata:
835
835
  """Validate every table of the data has a valid table/metadata pair."""
836
836
  errors = []
837
837
  warning_dataframes = []
838
+ tables_with_mismatching_columns_order = []
838
839
  for table_name, table_data in data.items():
839
840
  table_sdtype_warnings = defaultdict(list)
840
841
  try:
841
842
  with warnings.catch_warnings(record=True):
842
843
  self.tables[table_name].validate_data(table_data, table_sdtype_warnings)
844
+ if not self.tables[table_name]._check_data_columns_order(table_data.columns):
845
+ tables_with_mismatching_columns_order.append(table_name)
843
846
 
844
847
  except InvalidDataError as error:
845
848
  if INT_REGEX_ZERO_ERROR_MESSAGE in str(error) and len(self.tables) > 1:
@@ -877,6 +880,14 @@ class MultiTableMetadata:
877
880
  )
878
881
  warnings.warn(warning_msg)
879
882
 
883
+ if len(tables_with_mismatching_columns_order):
884
+ affected_tables = ', '.join(map(repr, tables_with_mismatching_columns_order))
885
+ warnings.warn(
886
+ 'The metadata lists columns in a different order than the data. '
887
+ 'This may result in the synthetic data having a different order.\n'
888
+ f'Affected tables: {affected_tables}.'
889
+ )
890
+
880
891
  return errors
881
892
 
882
893
  def _validate_foreign_keys(self, data):
@@ -1143,7 +1154,11 @@ class MultiTableMetadata:
1143
1154
  foreign_key = relationship.get('child_foreign_key')
1144
1155
  primary_key = self.tables.get(parent).primary_key
1145
1156
  edge_label = f' {foreign_key} → {primary_key}' if show_relationship_labels else ''
1146
- edges.append((parent, child, edge_label))
1157
+ child_primary_key = self.tables.get(child).primary_key
1158
+ if foreign_key == child_primary_key:
1159
+ edges.append((parent, child, edge_label, 'one-to-one'))
1160
+ else:
1161
+ edges.append((parent, child, edge_label))
1147
1162
 
1148
1163
  if show_table_details is not None:
1149
1164
  child_node = nodes.get(child)
@@ -1285,12 +1300,12 @@ class MultiTableMetadata:
1285
1300
  filepath (str):
1286
1301
  String that represents the ``path`` to the ``json`` file.
1287
1302
 
1303
+ Returns:
1304
+ A ``MultiTableMetadata`` instance.
1305
+
1288
1306
  Raises:
1289
1307
  - An ``Error`` if the path does not exist.
1290
1308
  - An ``Error`` if the ``json`` file does not contain the ``METADATA_SPEC_VERSION``.
1291
-
1292
- Returns:
1293
- A ``MultiTableMetadata`` instance.
1294
1309
  """
1295
1310
  metadata = read_json(filepath)
1296
1311
  return cls.load_from_dict(metadata)
@@ -1343,11 +1358,11 @@ class MultiTableMetadata:
1343
1358
  filepath (str):
1344
1359
  String that represents the ``path`` to the old metadata ``json`` file.
1345
1360
 
1346
- Raises:
1347
- Raises a ``ValueError`` if the filepath does not exist.
1348
-
1349
1361
  Returns:
1350
1362
  A ``MultiTableMetadata`` instance.
1363
+
1364
+ Raises:
1365
+ Raises a ``ValueError`` if the filepath does not exist.
1351
1366
  """
1352
1367
  old_metadata = read_json(filepath)
1353
1368
  tables_metadata = {}
@@ -1272,6 +1272,17 @@ class SingleTableMetadata:
1272
1272
 
1273
1273
  return []
1274
1274
 
1275
+ def _check_data_columns_order(self, data_columns):
1276
+ data_columns = [column for column in data_columns if column in self.columns]
1277
+ return data_columns == list(self.columns)
1278
+
1279
+ def _warn_data_column_order_mismatch(self, data_columns):
1280
+ if not self._check_data_columns_order(data_columns):
1281
+ warnings.warn(
1282
+ 'The metadata lists columns in a different order than the data. '
1283
+ 'This may result in the synthetic data having a different order.'
1284
+ )
1285
+
1275
1286
  def validate_data(self, data, sdtype_warnings=None):
1276
1287
  """Validate the data matches the metadata.
1277
1288
 
@@ -1304,6 +1315,9 @@ class SingleTableMetadata:
1304
1315
  # Both metadata and data must have the same set of columns
1305
1316
  self._validate_metadata_matches_data(data.columns)
1306
1317
 
1318
+ # Warn if metadata columns order mismatches data column order
1319
+ self._warn_data_column_order_mismatch(data.columns)
1320
+
1307
1321
  errors = []
1308
1322
  # Primary, sequence and alternate keys can't have missing values
1309
1323
  errors += self._validate_keys_dont_have_missing_values(data)
@@ -1490,12 +1504,12 @@ class SingleTableMetadata:
1490
1504
  filepath (str):
1491
1505
  String that represents the ``path`` to the ``json`` file.
1492
1506
 
1507
+ Returns:
1508
+ A ``SingleTableMetadata`` instance.
1509
+
1493
1510
  Raises:
1494
1511
  - An ``Error`` if the path does not exist.
1495
1512
  - An ``Error`` if the ``json`` file does not contain the ``METADATA_SPEC_VERSION``.
1496
-
1497
- Returns:
1498
- A ``SingleTableMetadata`` instance.
1499
1513
  """
1500
1514
  metadata = read_json(filepath)
1501
1515
  if 'METADATA_SPEC_VERSION' not in metadata:
@@ -1519,11 +1533,11 @@ class SingleTableMetadata:
1519
1533
  filepath (str):
1520
1534
  String that represents the ``path`` to the old metadata ``json`` file.
1521
1535
 
1522
- Raises:
1523
- Raises a ``ValueError`` if the filepath does not exist.
1524
-
1525
1536
  Returns:
1526
1537
  A ``SingleTableMetadata`` instance.
1538
+
1539
+ Raises:
1540
+ Raises a ``ValueError`` if the filepath does not exist.
1527
1541
  """
1528
1542
  old_metadata = read_json(filepath)
1529
1543
  if 'tables' in old_metadata:
@@ -102,8 +102,20 @@ def visualize_graph(nodes, edges, filepath=None):
102
102
  for name, label in nodes.items():
103
103
  digraph.node(name, label=_replace_special_characters(label))
104
104
 
105
- for parent, child, label in edges:
106
- digraph.edge(parent, child, label=_replace_special_characters(label), arrowhead='oinv')
105
+ for edge in edges:
106
+ parent, child, label = edge[0], edge[1], edge[2]
107
+ relation_type = edge[3] if len(edge) > 3 else 'one-to-many'
108
+ if relation_type == 'one-to-one':
109
+ digraph.edge(
110
+ parent,
111
+ child,
112
+ label=_replace_special_characters(label),
113
+ arrowhead='noneteeodot',
114
+ arrowtail='nonetee',
115
+ dir='both',
116
+ )
117
+ else:
118
+ digraph.edge(parent, child, label=_replace_special_characters(label), arrowhead='oinv')
107
119
 
108
120
  if filename:
109
121
  digraph.render(filename=filename, cleanup=True, format=graphviz_extension)
@@ -471,6 +471,7 @@ class HMASynthesizer(BaseHierarchicalSampler, BaseMultiTableSynthesizer):
471
471
  enforce_min_max_values=True
472
472
  )
473
473
  self.extended_columns[child_name][column].fit(extension, column)
474
+
474
475
  table = table.merge(extension, how='left', right_index=True, left_index=True)
475
476
  num_rows_key = f'__{child_name}__{foreign_key}__num_rows'
476
477
  table[num_rows_key] = table[num_rows_key].fillna(0)
@@ -485,11 +486,10 @@ class HMASynthesizer(BaseHierarchicalSampler, BaseMultiTableSynthesizer):
485
486
 
486
487
  tables[table_name] = table
487
488
  self._learned_relationships += 1
488
- self._augmented_tables.append(table_name)
489
489
 
490
+ self._augmented_tables.append(table_name)
490
491
  foreign_keys = self.metadata._get_all_foreign_keys(table_name)
491
492
  self._clear_nans(table, ignore_cols=foreign_keys)
492
-
493
493
  return table
494
494
 
495
495
  def _augment_tables(self, processed_data):
@@ -533,6 +533,7 @@ class HMASynthesizer(BaseHierarchicalSampler, BaseMultiTableSynthesizer):
533
533
  keys = {}
534
534
  for fk in foreign_keys:
535
535
  keys[fk] = table_data.pop(fk).to_numpy()
536
+
536
537
  return keys
537
538
 
538
539
  def _model_tables(self, augmented_data):
@@ -730,6 +731,7 @@ class HMASynthesizer(BaseHierarchicalSampler, BaseMultiTableSynthesizer):
730
731
  extended_columns = getattr(self, '_parent_extended_columns', {}).get(table_name, [])
731
732
  if extended_columns:
732
733
  self._set_extended_columns_distributions(synthesizer, table_name, extended_columns)
734
+
733
735
  synthesizer._set_parameters(parameters)
734
736
  try:
735
737
  likelihoods[parent_id] = synthesizer._get_likelihood(table_rows)
@@ -317,6 +317,7 @@ class BaseHierarchicalSampler:
317
317
  if num_rows <= 0:
318
318
  send_min_sample_warning = True
319
319
  num_rows = 1
320
+
320
321
  synthesizer = self._table_synthesizers[table]
321
322
  LOGGER.info(f'Sampling {num_rows} rows from table {table}')
322
323
  sampled_data[table] = self._sample_rows(synthesizer, num_rows)
@@ -341,5 +342,12 @@ class BaseHierarchicalSampler:
341
342
  )
342
343
  added_relationships.add((parent_name, child_name))
343
344
 
344
- sampled_data = self._reverse_transform_constraints(sampled_data)
345
+ # During this step, `drop_unknown_references` triggers `metadata.validate(data)`
346
+ # which now warns if the column order in the data does not match the metadata.
347
+ with warnings.catch_warnings():
348
+ warnings.filterwarnings(
349
+ 'ignore', message='The metadata lists columns in a different order than the data.'
350
+ )
351
+ sampled_data = self._reverse_transform_constraints(sampled_data)
352
+
345
353
  return self._finalize(sampled_data)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sdv
3
- Version: 1.34.1.dev0
3
+ Version: 1.34.2.dev0
4
4
  Summary: Generate synthetic data for single table, multi table and sequential data
5
5
  Author-email: "DataCebo, Inc." <info@sdv.dev>
6
6
  License-Expression: BUSL-1.1
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -24,12 +24,12 @@ class Metadata(MultiTableMetadata):
24
24
  filepath (str):
25
25
  String that represents the ``path`` to the ``json`` file.
26
26
 
27
+ Returns:
28
+ A ``Metadata`` instance.
29
+
27
30
  Raises:
28
31
  - An ``Error`` if the path does not exist.
29
32
  - An ``Error`` if the ``json`` file does not contain the ``METADATA_SPEC_VERSION``.
30
-
31
- Returns:
32
- A ``Metadata`` instance.
33
33
  """
34
34
  metadata = read_json(filepath)
35
35
  if metadata.get('METADATA_SPEC_VERSION') == 'SINGLE_TABLE_V1':
@@ -51,12 +51,12 @@ class LossValuesMixin:
51
51
  def get_loss_values(self):
52
52
  """Get the loss values from the model.
53
53
 
54
- Raises:
55
- - ``NotFittedError`` if synthesizer has not been fitted.
56
-
57
54
  Returns:
58
55
  pd.DataFrame:
59
56
  Dataframe containing the loss values per epoch.
57
+
58
+ Raises:
59
+ - ``NotFittedError`` if synthesizer has not been fitted.
60
60
  """
61
61
  if not self._fitted:
62
62
  err_msg = 'Loss values are not available yet. Please fit your synthesizer first.'
@@ -71,12 +71,12 @@ class LossValuesMixin:
71
71
  title (pd.DataFrame):
72
72
  Title string for the graph created.
73
73
 
74
- Raises:
75
- - ``NotFittedError`` if synthesizer has not been fitted.
76
-
77
74
  Returns:
78
75
  plotly.graph_objects._figure.Figure:
79
76
  1D marginal distribution plot (i.e. a histogram) of the columns.
77
+
78
+ Raises:
79
+ - ``NotFittedError`` if synthesizer has not been fitted.
80
80
  """
81
81
  if not self._fitted:
82
82
  err_msg = 'Loss values are not available yet. Please fit your synthesizer first.'
File without changes
File without changes
File without changes
File without changes