pandas-plots 0.9.5__tar.gz → 0.9.7__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.
- {pandas-plots-0.9.5/src/pandas_plots.egg-info → pandas-plots-0.9.7}/PKG-INFO +1 -1
- {pandas-plots-0.9.5 → pandas-plots-0.9.7}/setup.cfg +1 -1
- {pandas-plots-0.9.5 → pandas-plots-0.9.7}/src/pandas_plots/hlp.py +42 -3
- {pandas-plots-0.9.5 → pandas-plots-0.9.7}/src/pandas_plots/pls.py +6 -1
- {pandas-plots-0.9.5 → pandas-plots-0.9.7}/src/pandas_plots/tbl.py +20 -3
- {pandas-plots-0.9.5 → pandas-plots-0.9.7/src/pandas_plots.egg-info}/PKG-INFO +1 -1
- {pandas-plots-0.9.5 → pandas-plots-0.9.7}/LICENSE +0 -0
- {pandas-plots-0.9.5 → pandas-plots-0.9.7}/README.md +0 -0
- {pandas-plots-0.9.5 → pandas-plots-0.9.7}/pyproject.toml +0 -0
- {pandas-plots-0.9.5 → pandas-plots-0.9.7}/src/pandas_plots/ven.py +0 -0
- {pandas-plots-0.9.5 → pandas-plots-0.9.7}/src/pandas_plots.egg-info/SOURCES.txt +0 -0
- {pandas-plots-0.9.5 → pandas-plots-0.9.7}/src/pandas_plots.egg-info/dependency_links.txt +0 -0
- {pandas-plots-0.9.5 → pandas-plots-0.9.7}/src/pandas_plots.egg-info/requires.txt +0 -0
- {pandas-plots-0.9.5 → pandas-plots-0.9.7}/src/pandas_plots.egg-info/top_level.txt +0 -0
@@ -179,15 +179,23 @@ def create_barcode_from_url(
|
|
179
179
|
output_path: str | None = None,
|
180
180
|
show_image: bool = False,
|
181
181
|
):
|
182
|
+
"""
|
183
|
+
Create a barcode from the given URL. Uses "QR Code" from DENSO WAVE INCORPORATED.
|
184
|
+
|
185
|
+
Args:
|
186
|
+
url (str): The URL to encode in the barcode.
|
187
|
+
output_path (str | None, optional): The path to save the barcode image. Defaults to None.
|
188
|
+
show_image (bool, optional): Whether to display the barcode image. Defaults to False.
|
189
|
+
"""
|
182
190
|
WIDTH = 400
|
183
191
|
HEIGHT = 400
|
184
192
|
|
185
193
|
if not re.match(URL_REGEX, url):
|
186
|
-
print("
|
187
|
-
return
|
194
|
+
print("💡 Not a valid URL")
|
188
195
|
|
189
196
|
image = requests.get(
|
190
|
-
f"https://chart.googleapis.com/chart?chs={WIDTH}x{HEIGHT}&cht=qr&chl={url}"
|
197
|
+
# f"https://chart.googleapis.com/chart?chs={WIDTH}x{HEIGHT}&cht=qr&chl={url}"
|
198
|
+
f"https://api.qrserver.com/v1/create-qr-code/?size={WIDTH}x{HEIGHT}&data={url}"
|
191
199
|
)
|
192
200
|
image.raise_for_status()
|
193
201
|
|
@@ -202,3 +210,34 @@ def create_barcode_from_url(
|
|
202
210
|
plt.imshow(img)
|
203
211
|
# plt.axis('off') # Turn off axis numbers
|
204
212
|
plt.show()
|
213
|
+
|
214
|
+
def add_datetime_columns(df: pd.DataFrame, date_column: str = None) -> pd.DataFrame:
|
215
|
+
if not date_column:
|
216
|
+
date_column = [col for col in df.columns if pd.api.types.is_datetime64_any_dtype(df[col])][0]
|
217
|
+
|
218
|
+
if not date_column or not pd.api.types.is_datetime64_any_dtype(df[date_column]):
|
219
|
+
print("❌ No datetime column found")
|
220
|
+
return
|
221
|
+
|
222
|
+
if [col for col in df.columns if "YYYY-WW" in col]:
|
223
|
+
print("❌ Added datetime columns already exist")
|
224
|
+
return
|
225
|
+
|
226
|
+
print(f"⏳ Adding datetime columns basing off of: {date_column}")
|
227
|
+
df_= df.copy()
|
228
|
+
|
229
|
+
df_[date_column] = pd.to_datetime(df_[date_column])
|
230
|
+
|
231
|
+
df_["YYYY"] = df_[date_column].dt.year
|
232
|
+
df_["MM"] = df_[date_column].dt.month
|
233
|
+
df_["Q"] = df_[date_column].dt.quarter
|
234
|
+
|
235
|
+
df_["YYYY-MM"] = df_[date_column].dt.to_period("M").astype(str)
|
236
|
+
df_["YYYYQ"] = df_[date_column].dt.to_period("Q").astype(str)
|
237
|
+
df_["YYYY-WW"] = (
|
238
|
+
df_[date_column].dt.isocalendar().year.astype(str) + "-" +
|
239
|
+
df_[date_column].dt.isocalendar().week.astype(str).str.zfill(2)
|
240
|
+
)
|
241
|
+
df_["DDD"] = df_[date_column].dt.weekday.map({0: "Mon", 1: "Tue", 2: "Wed", 3: "Thu", 4: "Fri", 5: "Sat", 6: "Sun"})
|
242
|
+
|
243
|
+
return df_
|
@@ -111,6 +111,7 @@ def plot_stacked_bars(
|
|
111
111
|
caption: str = None,
|
112
112
|
sort_values: bool = False,
|
113
113
|
show_total: bool = False,
|
114
|
+
precision: int = 0,
|
114
115
|
) -> None:
|
115
116
|
"""
|
116
117
|
Generates a stacked bar plot using the provided DataFrame.
|
@@ -135,6 +136,7 @@ def plot_stacked_bars(
|
|
135
136
|
- caption: An optional string indicating the caption for the chart.
|
136
137
|
- sort_values: bool = False - Sort axis by index (default) or values
|
137
138
|
- show_total: bool = False - Whether to show the total value
|
139
|
+
- precision: int = 0 - The number of decimal places to round to
|
138
140
|
|
139
141
|
Returns:
|
140
142
|
None
|
@@ -166,6 +168,9 @@ def plot_stacked_bars(
|
|
166
168
|
df.iloc[:, 0] = df.iloc[:, 0].str.strip()
|
167
169
|
if df.iloc[:, 1].dtype.kind == "O":
|
168
170
|
df.iloc[:, 1] = df.iloc[:, 1].str.strip()
|
171
|
+
|
172
|
+
# * apply precision
|
173
|
+
df.iloc[:,2] = df.iloc[:,2].round(precision)
|
169
174
|
|
170
175
|
# * set index + color col
|
171
176
|
col_index = df.columns[0] if not swap else df.columns[1]
|
@@ -523,7 +528,7 @@ def plot_bars(
|
|
523
528
|
},
|
524
529
|
},
|
525
530
|
showlegend=False,
|
526
|
-
uniformtext_minsize=14, uniformtext_mode='hide'
|
531
|
+
# uniformtext_minsize=14, uniformtext_mode='hide'
|
527
532
|
|
528
533
|
)
|
529
534
|
# * sorting
|
@@ -14,10 +14,10 @@ from plotly.subplots import make_subplots
|
|
14
14
|
from scipy import stats
|
15
15
|
|
16
16
|
from .hlp import wrap_text
|
17
|
-
from devtools import debug
|
17
|
+
# from devtools import debug
|
18
|
+
pd.options.display.colheader_justify = "right"
|
18
19
|
# pd.options.mode.chained_assignment = None
|
19
20
|
|
20
|
-
|
21
21
|
TOTAL_LITERAL = Literal[
|
22
22
|
"sum", "mean", "median", "min", "max", "std", "var", "skew", "kurt"
|
23
23
|
]
|
@@ -36,6 +36,7 @@ def describe_df(
|
|
36
36
|
sort_mode: Literal["value", "index"] = "value",
|
37
37
|
top_n_uniques: int = 30,
|
38
38
|
top_n_chars_in_index: int = 0,
|
39
|
+
top_n_chars_in_columns: int = 0,
|
39
40
|
):
|
40
41
|
"""
|
41
42
|
This function takes a pandas DataFrame and a caption as input parameters and prints out the caption as a styled header, followed by the shape of the DataFrame and the list of column names. For each column, it prints out the column name, the number of unique values, and the column data type. If the column is a numeric column with more than 100 unique values, it also prints out the minimum, mean, maximum, and sum values. Otherwise, it prints out the first 100 unique values of the column.
|
@@ -52,6 +53,7 @@ def describe_df(
|
|
52
53
|
sort_mode (Literal["value", "index"]): sort by value or index
|
53
54
|
top_n_uniques (int): number of uniques to display
|
54
55
|
top_n_chars_in_index (int): number of characters to display on plot axis
|
56
|
+
top_n_chars_in_columns (int): number of characters to display on plot axis. If set, minimum is 10.
|
55
57
|
|
56
58
|
usage:
|
57
59
|
describe_df(
|
@@ -75,6 +77,11 @@ def describe_df(
|
|
75
77
|
print(f"DataFrame is empty!")
|
76
78
|
return
|
77
79
|
|
80
|
+
# ! fix bug(?) in plotly - empty float columns are not plotted, set these to str
|
81
|
+
for col in df.columns:
|
82
|
+
if df[col].notna().sum() == 0 and df[col].dtype == "float":
|
83
|
+
df[col] = df[col].astype(str)
|
84
|
+
|
78
85
|
print(f"🔵 {'*'*3} df: {caption} {'*'*3}")
|
79
86
|
print(f"🟣 shape: ({df.shape[0]:_}, {df.shape[1]}) columns: {df.columns.tolist()} ")
|
80
87
|
print(f"🟣 duplicates: {df.duplicated().sum():_}")
|
@@ -123,6 +130,15 @@ def describe_df(
|
|
123
130
|
# ! *** PLOTS ***
|
124
131
|
if not use_plot:
|
125
132
|
return
|
133
|
+
|
134
|
+
# * reduce column names len if selected
|
135
|
+
if top_n_chars_in_columns > 0:
|
136
|
+
# * minumum 10 chars, or display is cluttered
|
137
|
+
top_n_chars_in_columns = 10 if top_n_chars_in_columns < 10 else top_n_chars_in_columns
|
138
|
+
col_list = []
|
139
|
+
for i, col in enumerate(df.columns):
|
140
|
+
col_list.append(col[:top_n_chars_in_columns]+"_"+str(i).zfill(3))
|
141
|
+
df.columns = col_list
|
126
142
|
|
127
143
|
# * respect fig_offset to exclude unwanted plots from maintanance columns
|
128
144
|
cols = df.iloc[:, :fig_offset].columns
|
@@ -167,6 +183,7 @@ def describe_df(
|
|
167
183
|
else s[:top_n_chars_in_index]
|
168
184
|
)
|
169
185
|
x = [_cut(item) for item in x]
|
186
|
+
|
170
187
|
figsub = px.bar(
|
171
188
|
x=x,
|
172
189
|
y=y,
|
@@ -346,7 +363,7 @@ def show_num_df(
|
|
346
363
|
"""
|
347
364
|
# * ensure arguments match parameter definition
|
348
365
|
if any([df[col].dtype.kind not in ["i", "u", "f"] for col in df.columns]) == True:
|
349
|
-
print(f"❌ table must contain numeric data only")
|
366
|
+
print(f"❌ table must contain numeric data only. Maybe you forgot to convert this table with pivot or pivot_table first?")
|
350
367
|
return
|
351
368
|
|
352
369
|
if (
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|