pandas-plots 0.12.15__py3-none-any.whl → 0.12.17__py3-none-any.whl

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.
pandas_plots/hlp.py CHANGED
@@ -6,6 +6,8 @@ from enum import Enum, auto
6
6
  from io import BytesIO
7
7
  from platform import python_version
8
8
  from typing import List, Literal
9
+ import json
10
+ import uuid
9
11
 
10
12
  import duckdb as ddb
11
13
  import numpy as np
@@ -490,4 +492,56 @@ def find_cols(all_cols: list[str], stubs=list[str]):
490
492
  return [col for col in all_cols if any(match in col for match in stubs)]
491
493
 
492
494
  # * extend objects to enable chaining
493
- pd.DataFrame.find_cols = find_cols
495
+ pd.DataFrame.find_cols = find_cols
496
+
497
+ def add_measures_to_pyg_config(json_path: str, nodes: list[tuple[str, str]]) -> None:
498
+ """
499
+ Reads a pygwalker json config file, adds new measures from given nodes if not already present, and writes back to the file.
500
+
501
+ Parameters
502
+ ----------
503
+ json_path : `str`
504
+ The path to the pyg_json config file.
505
+ nodes : `list[tuple[str, str]]`
506
+ A list of tuples, where the first element in the tuple is the name of the measure and the second element is the SQL expression that defines the measure.
507
+
508
+ Returns
509
+ -------
510
+ None
511
+
512
+ Example
513
+ -------
514
+ `node = [("cnt_tum", "count(distinct z_tum_id)")]`
515
+ """
516
+
517
+ with open(json_path, "r", encoding="utf-8") as file:
518
+ config = json.load(file)
519
+
520
+ for node in nodes:
521
+ fid = uuid.uuid4().hex
522
+
523
+ # Define the measure
524
+ new_json_node = {
525
+ "analyticType": "measure",
526
+ "fid": f"{fid}",
527
+ "name": f"{node[0]}",
528
+ "semanticType": "quantitative",
529
+ "computed": True,
530
+ "aggName": "expr",
531
+ "expression": {
532
+ "op": "expr",
533
+ "as": f"{fid}",
534
+ "params": [{"type": "sql", "value": f"{node[1]}"}]
535
+ }
536
+ }
537
+
538
+ # Get the measures list
539
+ measures = config["config"][0]["encodings"]["measures"]
540
+
541
+ # Ensure the measure is present
542
+ if not any(measure.get("name") == node[0] for measure in measures):
543
+ measures.append(new_json_node)
544
+
545
+ # Write the updated JSON back to the file
546
+ with open(json_path, "w", encoding="utf-8") as file:
547
+ json.dump(config, file, indent=2)
pandas_plots/pls.py CHANGED
@@ -661,7 +661,6 @@ def plot_bars(
661
661
 
662
662
  # * layot caption if provided
663
663
  caption = _set_caption(caption)
664
-
665
664
  # ! plot
666
665
  _fig = px.bar(
667
666
  df.sort_values(
@@ -674,7 +673,7 @@ def plot_bars(
674
673
  orientation=orientation,
675
674
  # * retrieve the original columns from series
676
675
  title=title
677
- or f"{caption}{_title_str_minval}{_title_str_top}[{df.columns[1]}] by [{col_index}]{_title_str_null}{_title_str_n}",
676
+ or f"{caption}{_title_str_minval}{_title_str_top}[{col_name}] by [{col_index}]{_title_str_null}{_title_str_n}",
678
677
  # * retrieve theme from env (intro.set_theme) or default
679
678
  template="plotly_dark" if os.getenv("THEME") == "dark" else "plotly",
680
679
  width=width,
@@ -732,8 +731,22 @@ def plot_bars(
732
731
 
733
732
  # * looks better on single bars
734
733
  _fig.update_traces(
735
- textposition="outside" if not use_ci else "auto", error_y=dict(thickness=5)
734
+ error_y=dict(thickness=5)
736
735
  )
736
+ if use_ci:
737
+ _fig.update_traces(
738
+ textposition="inside", # Put labels inside bars
739
+ insidetextanchor="start", # Align labels at the bottom
740
+ textfont=dict(size=14, color="white") # Adjust text color for visibility
741
+ )
742
+ else:
743
+ _fig.update_traces(
744
+ textposition="outside",
745
+ # error_y=dict(thickness=0)
746
+ )
747
+
748
+ # * set axis title
749
+
737
750
  _fig.show(renderer)
738
751
 
739
752
  # * save to png if path is provided
pandas_plots/tbl.py CHANGED
@@ -57,7 +57,7 @@ def descr_db(
57
57
  print(f'🗄️ {caption}\t{db.count("*").fetchone()[0]:_}, {db.columns.__len__()}\n\t("{cols}")')
58
58
 
59
59
  if use_preview:
60
- db.limit(3).show()
60
+ db.limit(3).show(max_width=2000)
61
61
  return
62
62
 
63
63
  def describe_df(
@@ -269,6 +269,7 @@ def pivot_df(
269
269
  alter_font: bool = True,
270
270
  font_size_th: int = 0,
271
271
  font_size_td: int = 0,
272
+ col1_width: int = 0,
272
273
  png_path: str | Path = None,
273
274
  png_conversion: Literal["chrome", "selenium"] = "selenium",
274
275
  ) -> pd.DataFrame:
@@ -306,6 +307,7 @@ def pivot_df(
306
307
  alter_font (bool, optional): Whether to alter the font. Defaults to True.
307
308
  font_size_th (int, optional): The font size for the header. Defaults to 0.
308
309
  font_size_td (int, optional): The font size for the table data. Defaults to 0.
310
+ col1_width (int, optional): The width of the first column in px. Defaults to 0.
309
311
  png_path (str | Path, optional): The path to save the output PNG file. Defaults to None.
310
312
  png_conversion (Literal["chrome", "selenium"], optional): The conversion method for the PNG file. Defaults to "selenium".
311
313
 
@@ -393,6 +395,7 @@ def pivot_df(
393
395
  alter_font=alter_font,
394
396
  font_size_th=font_size_th,
395
397
  font_size_td=font_size_td,
398
+ col1_width=col1_width,
396
399
  png_path=png_path,
397
400
  png_conversion=png_conversion,
398
401
 
@@ -416,6 +419,7 @@ def show_num_df(
416
419
  alter_font: bool = True,
417
420
  font_size_th: int = 0,
418
421
  font_size_td: int = 0,
422
+ col1_width: int = 0,
419
423
  png_path: str | Path = None,
420
424
  png_conversion: Literal["chrome", "selenium"] = "selenium",
421
425
  ):
@@ -445,6 +449,7 @@ def show_num_df(
445
449
  - alter_font: a boolean indicating whether to alter the font family
446
450
  - font_size_th: an integer indicating the font size for the header
447
451
  - font_size_td: an integer indicating the font size for the table data
452
+ - col1_width: an integer indicating the width of the first column in px
448
453
  - png_path: a string or Path indicating the path to save the PNG file
449
454
  - png_conversion: a Literal indicating the conversion method for the PNG file ["chrome", "selenium"]
450
455
 
@@ -680,6 +685,15 @@ def show_num_df(
680
685
  dict(selector="td", props=_props_td),
681
686
  ]
682
687
  )
688
+
689
+ if col1_width > 0:
690
+ out.set_table_styles([
691
+ {'selector': 'th:first-child, td:first-child',
692
+ 'props': [(f'min-width', f'{col1_width}px !important'),
693
+ (f'max-width', f'{col1_width}px !important'),
694
+ ('white-space', 'nowrap'),
695
+ ('overflow', 'hidden')]}
696
+ ])
683
697
 
684
698
  if heatmap_axis:
685
699
  out.background_gradient(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pandas-plots
3
- Version: 0.12.15
3
+ Version: 0.12.17
4
4
  Summary: A collection of helper for table handling and visualization
5
5
  Home-page: https://github.com/smeisegeier/pandas-plots
6
6
  Author: smeisegeier
@@ -115,6 +115,7 @@ tbl.show_num_df(
115
115
  - `get_os` helps to identify and ensure operating system at runtime
116
116
  - `add_bitmask_label()` adds a column to the data that resolves a bitmask column into human-readable labels
117
117
  - `find_cols()` finds all columns in a list of columns that contain any of the given stubs
118
+ - `add_measures_to_pyg_config()` adds measures to a pygwalker config file to avoid frequent manual update
118
119
  <br>
119
120
 
120
121
  - `pii` has routines for handling of personally identifiable information
@@ -0,0 +1,11 @@
1
+ pandas_plots/hlp.py,sha256=ggIe9uwF4tlVWqaBxQOkn8Dz8955xjY-TYG-lzypWFE,18905
2
+ pandas_plots/pii.py,sha256=2WKE-W9s285jPdsTqCgt1uxuW4lj1PYCVOYB2fYDNwQ,2195
3
+ pandas_plots/pls.py,sha256=YbWPk34oJ3SJ-n7O-FvMOYR2FT2uNbMe93E0dbVTetk,48170
4
+ pandas_plots/tbl.py,sha256=LxMKJh4qkGuQZ1DdCZIq1tMS26F6elsqbe_uabvQx4E,32535
5
+ pandas_plots/ven.py,sha256=2x3ACo2vSfO3q6fv-UdDQ0h1SJyt8WChBGgE5SDCdCk,11673
6
+ pandas_plots-0.12.17.dist-info/LICENSE,sha256=6KQ5KVAAhRaB-JJKpX4cefKvRZRgI7GUPc92_2d31XY,1051
7
+ pandas_plots-0.12.17.dist-info/METADATA,sha256=SVkqVo2s4V_1kd9dk5PuHQe6svOxRLLusfYI--jKzsM,7550
8
+ pandas_plots-0.12.17.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
9
+ pandas_plots-0.12.17.dist-info/pii.py,sha256=2WKE-W9s285jPdsTqCgt1uxuW4lj1PYCVOYB2fYDNwQ,2195
10
+ pandas_plots-0.12.17.dist-info/top_level.txt,sha256=XnaNuIHBqMmCeh_U7nKOYTwFue_SIA0wxuDgdPmnnSk,13
11
+ pandas_plots-0.12.17.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.2)
2
+ Generator: setuptools (76.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,11 +0,0 @@
1
- pandas_plots/hlp.py,sha256=eKJaQqd03tYlbWXoicHi9j32zrNlpIQngj4Dni2fYTo,17230
2
- pandas_plots/pii.py,sha256=2WKE-W9s285jPdsTqCgt1uxuW4lj1PYCVOYB2fYDNwQ,2195
3
- pandas_plots/pls.py,sha256=OLaX5gWbsuYniikpojqPxZt9oQK_PI1XyJEQkbNlSk8,47809
4
- pandas_plots/tbl.py,sha256=205LfHkLhZKvqaIqPGEo-t6m7nLPTT5FNGVfVH_o1WA,31916
5
- pandas_plots/ven.py,sha256=2x3ACo2vSfO3q6fv-UdDQ0h1SJyt8WChBGgE5SDCdCk,11673
6
- pandas_plots-0.12.15.dist-info/LICENSE,sha256=6KQ5KVAAhRaB-JJKpX4cefKvRZRgI7GUPc92_2d31XY,1051
7
- pandas_plots-0.12.15.dist-info/METADATA,sha256=c7RcgTtnI2qpgk5Xm8Uu67rGmeRf1Nw1V5uXZTnmyRc,7442
8
- pandas_plots-0.12.15.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
9
- pandas_plots-0.12.15.dist-info/pii.py,sha256=2WKE-W9s285jPdsTqCgt1uxuW4lj1PYCVOYB2fYDNwQ,2195
10
- pandas_plots-0.12.15.dist-info/top_level.txt,sha256=XnaNuIHBqMmCeh_U7nKOYTwFue_SIA0wxuDgdPmnnSk,13
11
- pandas_plots-0.12.15.dist-info/RECORD,,