Added SNS plot/chart nodes to use Seaborn for plot/chart moving forward.
This commit is contained in:
@@ -8,7 +8,7 @@ ComfyUI was designed to make Stable Diffusion accessible to non-engineers while
|
||||
|
||||
At the end of this page, you’ll find a tutorial on how to use this package to answer the MLB hits question.
|
||||
|
||||
I hope you enjoy using it and have a great time exploring data.
|
||||
I hope you find it useful and engaging for data exploration.
|
||||
|
||||
— Hide Inada
|
||||
|
||||
@@ -36,7 +36,7 @@ Here are just some of the included nodes. For a complete list of nodes, check ou
|
||||
You can connect these nodes to conduct complex analysis in an intuitive graphical way.
|
||||
You can also use other Comfy custom nodes to fit your needs (e.g., combining images).
|
||||
|
||||
These custom nodes aim to make data exploration and analysis more efficient and enjoyable.
|
||||
These custom nodes enhance efficiency and usability in data exploration and analysis.
|
||||
|
||||
## Installation
|
||||
Note: GPU is not required to run this custom module.
|
||||
@@ -58,7 +58,7 @@ Note: GPU is not required to run this custom module.
|
||||
```
|
||||
This will create a new subdirectory ComfyUI-Data-Analysis.
|
||||
3. Rename the folder name from ComfyUI-Data-Analysis to data-analysis.
|
||||
If you skip this, example workflows will not work as those flows use this folder name.
|
||||
Skipping this step will cause example workflows to fail, as they rely on this folder name.
|
||||
4. Check if your ComfyUI environment already has pandas and matplotlib. If not, install them using pip.
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
@@ -75,7 +75,7 @@ Refer to [User's Guide](docs/ug.md) or check out [Node Reference](docs/reference
|
||||
For a practical example, see the tutorial on baseball data: [How to Find Out Who Had the Most Hits](docs/baseball_example1.md).
|
||||
|
||||
## Update
|
||||
Please refer to the release notes. I try to avoid backward-incompatible changes as much as possible, but sometimes they are unavoidable because the project is still in its early stage and I discover issues along the way. The release notes contain those changes so that you know what to expect before upgrading your version.
|
||||
Refer to the release notes. While backward-incompatible changes are minimized, some may be necessary. The release notes contain those changes so that you know what to expect before upgrading your version.
|
||||
|
||||
## Contribution
|
||||
🚫 **This project does not accept pull requests.**
|
||||
|
||||
@@ -105,6 +105,9 @@ from .modules.pandas_wrapper.pandas_var import PandasVar
|
||||
from .modules.pandas_wrapper.pandas_vertical_concat import PandasVerticalConcat
|
||||
from .modules.pandas_wrapper.pandas_vertical_split import PandasVerticalSplit
|
||||
from .modules.pandas_wrapper.pandas_xs import PandasXs
|
||||
from .modules.seaborn_wrapper.sns_bar import SNSBar
|
||||
from .modules.seaborn_wrapper.sns_line import SNSLine
|
||||
from .modules.seaborn_wrapper.sns_scatter import SNSScatter
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
@@ -219,6 +222,9 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = {
|
||||
"PandasVerticalConcat": PandasVerticalConcat,
|
||||
"PandasVerticalSplit": PandasVerticalSplit,
|
||||
"PandasXs": PandasXs,
|
||||
"SNSBar": SNSBar,
|
||||
"SNSLine": SNSLine,
|
||||
"SNSScatter": SNSScatter,
|
||||
}
|
||||
|
||||
|
||||
@@ -333,6 +339,9 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = {
|
||||
"PandasVerticalConcat": "Pandas Vertical Concat",
|
||||
"PandasVerticalSplit": "Pandas Vertical Split",
|
||||
"PandasXs": "Pandas Xs",
|
||||
"SNSBar": "SNS Bar Chart",
|
||||
"SNSLine": "SNS Line Plot",
|
||||
"SNSScatter": "SNS Scatter Plot",
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -76,12 +76,16 @@ def format_display_name(class_name):
|
||||
("CD A", "CDA"),
|
||||
("H T M L", "HTML"),
|
||||
("MP L", "MPL"),
|
||||
("SN S", "SNS"),
|
||||
(" N A", " NA"),
|
||||
("Data Frame", "DataFrame"),
|
||||
("Multi Index", "MultiIndex"),
|
||||
("MPL Bar", "MPL Bar Chart"),
|
||||
("MPL Line", "MPL Line Plot"),
|
||||
("MPL Scatter", "MPL Scatter Plot")
|
||||
("MPL Scatter", "MPL Scatter Plot"),
|
||||
("SNS Bar", "SNS Bar Chart"),
|
||||
("SNS Line", "SNS Line Plot"),
|
||||
("SNS Scatter", "SNS Scatter Plot")
|
||||
]
|
||||
for p in replace_pairs:
|
||||
final_result = final_result.replace(p[0], p[1])
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 123 KiB |
@@ -114,6 +114,9 @@
|
||||
| [MPL Bar Chart](mpl_bar.md) | Generates a bar chart from a Pandas DataFrame. |
|
||||
| [MPL Line Plot](mpl_line.md) | Generates a line plot from a pandas DataFrame. |
|
||||
| [MPL Scatter Plot](mpl_scatter.md) | Generates a scatter plot from a pandas DataFrame. |
|
||||
| [SNS Bar Chart](sns_bar.md) | Generates a bar chart from a Pandas DataFrame using Seaborn. |
|
||||
| [SNS Line Plot](sns_line.md) | Generates a line plot from a pandas DataFrame using Seaborn. |
|
||||
| [SNS Scatter Plot](sns_scatter.md) | Generates a scatter plot from a pandas DataFrame using Seaborn. |
|
||||
## Summary statistics
|
||||
| Node | Description |
|
||||
| --- | --- |
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# SNS Bar Chart
|
||||
Generates a bar chart from a Pandas DataFrame using Seaborn.
|
||||
|
||||
For style and palette parameters, refer to [SNS Line Plot documentation](sns_line.md).
|
||||
|
||||
## Output
|
||||
| Data type |
|
||||
|---|
|
||||
| Image |
|
||||
|
||||
<HR>
|
||||
Category: Plot
|
||||
|
||||
ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved.
|
||||
@@ -0,0 +1,33 @@
|
||||
# SNS Line Plot
|
||||
Generates a line plot from a pandas DataFrame using Seaborn.
|
||||
|
||||
For plotting multiple lines, enter a comma-separated column labels in y_column_name.
|
||||
If you want to display a legend for each line, enter a comma-separated legend label
|
||||
in legend label.
|
||||
|
||||

|
||||
|
||||
The `style` parameter can be chosen from:
|
||||
* darkgrid (default) – Grid with a dark background.
|
||||
* whitegrid – Grid with a white background.
|
||||
* dark – Dark background, no grid.
|
||||
* white – White background, no grid.
|
||||
* ticks – White background with tick marks.
|
||||
|
||||
The `palette` parameter can be chosen from:
|
||||
* deep (default) – High contrast, good for multiple categories.
|
||||
* muted – Softer colors, easier on the eyes.
|
||||
* pastel – Light colors, suitable for minimalistic styles.
|
||||
* bright – Vibrant and highly saturated colors.
|
||||
* dark – Darker, high-contrast colors.
|
||||
* colorblind – Optimized for color vision deficiencies.
|
||||
|
||||
## Output
|
||||
| Data type |
|
||||
|---|
|
||||
| Image |
|
||||
|
||||
<HR>
|
||||
Category: Plot
|
||||
|
||||
ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved.
|
||||
@@ -0,0 +1,14 @@
|
||||
# SNS Scatter Plot
|
||||
Generates a scatter plot from a pandas DataFrame using Seaborn.
|
||||
|
||||
For style and palette parameters, refer to [SNS Line Plot documentation](sns_line.md).
|
||||
|
||||
## Output
|
||||
| Data type |
|
||||
|---|
|
||||
| Image |
|
||||
|
||||
<HR>
|
||||
Category: Plot
|
||||
|
||||
ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved.
|
||||
@@ -27,6 +27,21 @@ def flatten_list_tuple_unique(lst: Union[List[Any], Tuple[Any, ...]]) -> Set[Any
|
||||
recurse(lst)
|
||||
return result
|
||||
|
||||
def comma_separated_labels_string_to_list(s:str) -> List[str]:
|
||||
"""
|
||||
Converts a comma-separated labels string into a list of string labels.
|
||||
|
||||
Args:
|
||||
s (str): A comma-separated labels.
|
||||
|
||||
Returns:
|
||||
List[str]: A list of valid labels.
|
||||
"""
|
||||
if s is None or s == "":
|
||||
return []
|
||||
label_list = [e.strip() for e in s.split(",")]
|
||||
return label_list
|
||||
|
||||
|
||||
def column_labels_string_to_list(dataframe:pd.DataFrame, s:str, no_check:bool=False) -> List[Union[str, int]]:
|
||||
"""
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
def common_input_types():
|
||||
"""
|
||||
Defines the input types for a plot function.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: A dictionary specifying required input types.
|
||||
"""
|
||||
return {
|
||||
"required": {
|
||||
"dataframe": ("DATAFRAME", {}),
|
||||
"x_column_name": ("STRING", {"default": ""}),
|
||||
"y_column_name": ("STRING", {"default": ""}),
|
||||
"title": ("STRING", {"default": ""}),
|
||||
"x_axis_label": ("STRING", {"default": ""}),
|
||||
"y_axis_label": ("STRING", {"default": ""}),
|
||||
"legend_label": ("STRING", {"default": ""}),
|
||||
"x_tick_as_int": ("BOOLEAN", {"default": False}), # To show 2002 instead of 2002.5 on x-axis
|
||||
"style": ("STRING", {"default": ""}),
|
||||
"palette": ("STRING", {"default": ""})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
from typing import Any, Dict
|
||||
from matplotlib import pyplot as plt
|
||||
import pandas as pd
|
||||
import seaborn as sns
|
||||
from .common import common_input_types
|
||||
from .util import plot_post_steps
|
||||
from .util import set_up_sns_style_palette
|
||||
from .util import process_y_columns_and_labels
|
||||
|
||||
|
||||
class SNSBar:
|
||||
"""
|
||||
SNS Bar Chart:
|
||||
Generates a bar chart from a Pandas DataFrame using Seaborn.
|
||||
|
||||
For style and palette parameters, refer to [SNS Line Plot documentation](sns_line.md).
|
||||
|
||||
category: Plot
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Dict[str, Any]:
|
||||
"""
|
||||
Defines the input types for the `bar_chart` function.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: A dictionary specifying required input types.
|
||||
"""
|
||||
return common_input_types()
|
||||
|
||||
RETURN_TYPES: tuple = ("IMAGE",)
|
||||
FUNCTION: str = "bar_chart"
|
||||
CATEGORY: str = "Data Analysis"
|
||||
|
||||
def bar_chart(self,
|
||||
dataframe: pd.DataFrame,
|
||||
x_column_name: str,
|
||||
y_column_name: str,
|
||||
title: str,
|
||||
x_axis_label: str,
|
||||
y_axis_label: str,
|
||||
legend_label: str,
|
||||
x_tick_as_int: bool,
|
||||
style: str=None,
|
||||
palette: str=None) -> tuple:
|
||||
"""
|
||||
Generates a bar chart from a pandas DataFrame.
|
||||
|
||||
Args:
|
||||
dataframe (DataFrame): The DataFrame.
|
||||
x_column_name (str): The column name for the x-axis.
|
||||
y_column_name (str): The column name for the y-axis.
|
||||
title (str): The title of the plot.
|
||||
x_axis_label (str): The label for the x-axis data.
|
||||
y_axis_label (str): The label for the y-axis data.
|
||||
x_tick_as_int (bool): If set, use integers for x ticks. For example,
|
||||
if ticks show floating point numbers for years, e.g. 2002.5,
|
||||
setting this flag will show integer values instead.
|
||||
style (str): Style of the plot
|
||||
palette (str): Palette of the plot
|
||||
Returns:
|
||||
tuple: A tuple containing the image tensor representation of the plot.
|
||||
"""
|
||||
df = dataframe
|
||||
set_up_sns_style_palette(style, palette)
|
||||
y_columns, labels = process_y_columns_and_labels(df, y_column_name, legend_label)
|
||||
|
||||
# Create the plot
|
||||
fig, ax = plt.subplots()
|
||||
for i in range(len(y_columns)):
|
||||
sns.barplot(x=df[x_column_name], y=df[y_columns[i]], ax=ax, label=labels[i])
|
||||
|
||||
return plot_post_steps(
|
||||
fig,
|
||||
ax,
|
||||
plt,
|
||||
title,
|
||||
x_axis_label,
|
||||
y_axis_label,
|
||||
x_tick_as_int)
|
||||
@@ -0,0 +1,99 @@
|
||||
from typing import Any, Dict
|
||||
from matplotlib import pyplot as plt
|
||||
import seaborn as sns
|
||||
import pandas as pd
|
||||
from .common import common_input_types
|
||||
from .util import plot_post_steps
|
||||
from .util import set_up_sns_style_palette
|
||||
from .util import process_y_columns_and_labels
|
||||
|
||||
|
||||
class SNSLine:
|
||||
"""
|
||||
SNS Line Plot:
|
||||
Generates a line plot from a pandas DataFrame using Seaborn.
|
||||
|
||||
For plotting multiple lines, enter a comma-separated column labels in y_column_name.
|
||||
If you want to display a legend for each line, enter a comma-separated legend label
|
||||
in legend label.
|
||||
|
||||

|
||||
|
||||
The `style` parameter can be chosen from:
|
||||
* darkgrid (default) – Grid with a dark background.
|
||||
* whitegrid – Grid with a white background.
|
||||
* dark – Dark background, no grid.
|
||||
* white – White background, no grid.
|
||||
* ticks – White background with tick marks.
|
||||
|
||||
The `palette` parameter can be chosen from:
|
||||
* deep (default) – High contrast, good for multiple categories.
|
||||
* muted – Softer colors, easier on the eyes.
|
||||
* pastel – Light colors, suitable for minimalistic styles.
|
||||
* bright – Vibrant and highly saturated colors.
|
||||
* dark – Darker, high-contrast colors.
|
||||
* colorblind – Optimized for color vision deficiencies.
|
||||
|
||||
category: Plot
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Dict[str, Any]:
|
||||
"""
|
||||
Defines the input types for the `line_plot` function.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: A dictionary specifying required input types.
|
||||
"""
|
||||
return common_input_types()
|
||||
|
||||
RETURN_TYPES: tuple = ("IMAGE",)
|
||||
FUNCTION: str = "line_plot"
|
||||
CATEGORY: str = "Data Analysis"
|
||||
|
||||
def line_plot(self,
|
||||
dataframe: pd.DataFrame,
|
||||
x_column_name: str,
|
||||
y_column_name: str,
|
||||
title: str,
|
||||
x_axis_label: str,
|
||||
y_axis_label: str,
|
||||
legend_label: str,
|
||||
x_tick_as_int: bool,
|
||||
style: str=None,
|
||||
palette: str=None) -> tuple:
|
||||
"""
|
||||
Generates a line plot from a pandas DataFrame.
|
||||
|
||||
Args:
|
||||
dataframe (DataFrame): The DataFrame.
|
||||
x_column_name (str): The column name for the x-axis.
|
||||
y_column_name (str): The column name for the y-axis.
|
||||
title (str): The title of the plot.
|
||||
x_axis_label (str): The label for the x-axis data.
|
||||
y_axis_label (str): The label for the y-axis data.
|
||||
legend_label (str): The legend label of the plot.
|
||||
x_tick_as_int (bool): If set, use integers for x ticks. For example,
|
||||
if ticks show floating point numbers for years, e.g. 2002.5,
|
||||
setting this flag will show integer values instead.
|
||||
style (str): Style of the plot
|
||||
palette (str): Palette of the plot
|
||||
Returns:
|
||||
tuple: A tuple containing the image tensor representation of the plot.
|
||||
"""
|
||||
df = dataframe
|
||||
set_up_sns_style_palette(style, palette)
|
||||
y_columns, labels = process_y_columns_and_labels(df, y_column_name, legend_label)
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
for i in range(len(y_columns)):
|
||||
sns.lineplot(x=df[x_column_name], y=df[y_columns[i]], ax=ax, label=labels[i])
|
||||
|
||||
return plot_post_steps(
|
||||
fig,
|
||||
ax,
|
||||
plt,
|
||||
title,
|
||||
x_axis_label,
|
||||
y_axis_label,
|
||||
x_tick_as_int)
|
||||
@@ -0,0 +1,80 @@
|
||||
from typing import Any, Dict
|
||||
from matplotlib import pyplot as plt
|
||||
import seaborn as sns
|
||||
import pandas as pd
|
||||
from .common import common_input_types
|
||||
from .util import plot_post_steps
|
||||
from .util import set_up_sns_style_palette
|
||||
from .util import process_y_columns_and_labels
|
||||
|
||||
|
||||
class SNSScatter:
|
||||
"""
|
||||
SNS Scatter Plot:
|
||||
Generates a scatter plot from a pandas DataFrame using Seaborn.
|
||||
|
||||
For style and palette parameters, refer to [SNS Line Plot documentation](sns_line.md).
|
||||
|
||||
category: Plot
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Dict[str, Any]:
|
||||
"""
|
||||
Defines the input types for the `scatter_plot` function.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: A dictionary specifying required input types.
|
||||
"""
|
||||
return common_input_types()
|
||||
|
||||
RETURN_TYPES: tuple = ("IMAGE",)
|
||||
FUNCTION: str = "scatter_plot"
|
||||
CATEGORY: str = "Data Analysis"
|
||||
|
||||
def scatter_plot(self,
|
||||
dataframe: pd.DataFrame,
|
||||
x_column_name: str,
|
||||
y_column_name: str,
|
||||
title: str,
|
||||
x_axis_label: str,
|
||||
y_axis_label: str,
|
||||
legend_label: str,
|
||||
x_tick_as_int: bool,
|
||||
style: str=None,
|
||||
palette: str=None) -> tuple:
|
||||
"""
|
||||
Generates a scatter plot from a pandas DataFrame.
|
||||
|
||||
Args:
|
||||
dataframe (DataFrame): The DataFrame.
|
||||
x_column_name (str): The column name for the x-axis.
|
||||
y_column_name (str): The column name for the y-axis.
|
||||
title (str): The title of the plot.
|
||||
x_axis_label (str): The label for the x-axis data.
|
||||
y_axis_label (str): The label for the y-axis data.
|
||||
x_tick_as_int (bool): If set, use integers for x ticks. For example,
|
||||
if ticks show floating point numbers for years, e.g. 2002.5,
|
||||
setting this flag will show integer values instead.
|
||||
style (str): Style of the plot
|
||||
palette (str): Palette of the plot
|
||||
Returns:
|
||||
tuple: A tuple containing the image tensor representation of the plot.
|
||||
"""
|
||||
df = dataframe
|
||||
set_up_sns_style_palette(style, palette)
|
||||
y_columns, labels = process_y_columns_and_labels(df, y_column_name, legend_label)
|
||||
|
||||
# Create the plot
|
||||
fig, ax = plt.subplots()
|
||||
for i in range(len(y_columns)):
|
||||
sns.scatterplot(x=df[x_column_name], y=df[y_columns[i]], ax=ax, label=labels[i])
|
||||
|
||||
return plot_post_steps(
|
||||
fig,
|
||||
ax,
|
||||
plt,
|
||||
title,
|
||||
x_axis_label,
|
||||
y_axis_label,
|
||||
x_tick_as_int)
|
||||
@@ -0,0 +1,106 @@
|
||||
import io
|
||||
from typing import List, Tuple
|
||||
import numpy as np
|
||||
import matplotlib.figure
|
||||
import matplotlib.axes
|
||||
from matplotlib import pyplot as plt
|
||||
import matplotlib.ticker as mticker
|
||||
import seaborn as sns
|
||||
from PIL import Image
|
||||
import torch
|
||||
import pandas as pd
|
||||
import seaborn as sns
|
||||
from typing import Optional
|
||||
from ..pandas_wrapper.utils import column_labels_string_to_list
|
||||
from ..pandas_wrapper.utils import comma_separated_labels_string_to_list
|
||||
|
||||
|
||||
def process_y_columns_and_labels(df:pd.DataFrame, y_column_name: str, legend_label: str) -> Tuple[List[str], List[str]]:
|
||||
"""
|
||||
Generates a y column list and legend label list from the comma-separated y column names and legend label string.
|
||||
|
||||
Args:
|
||||
df (pd.DataFrame): The input dataframe containing the data.
|
||||
y_column_name (str): A comma-separated string of column names to be used as y-values.
|
||||
legend_label (str): A comma-separated string of labels corresponding to the y columns.
|
||||
|
||||
Returns:
|
||||
List[str]: A list of processed y column names.
|
||||
List[str]: A list of processed legend labels.
|
||||
"""
|
||||
y_columns = column_labels_string_to_list(df, y_column_name)
|
||||
if legend_label:
|
||||
labels = comma_separated_labels_string_to_list(legend_label)
|
||||
if len(labels) < len(y_columns):
|
||||
labels = labels + [""] * (len(y_columns) - len(labels))
|
||||
else:
|
||||
labels = [""] * len(y_columns)
|
||||
|
||||
return y_columns, labels
|
||||
|
||||
|
||||
def set_up_sns_style_palette(style: Optional[str], palette: Optional[str]) -> None:
|
||||
"""
|
||||
Sets the Seaborn theme with the given style and palette.
|
||||
|
||||
Args:
|
||||
style (Optional[str]): The style to apply to the Seaborn theme (e.g., 'darkgrid', 'whitegrid').
|
||||
palette (Optional[str]): The color palette to apply (e.g., 'deep', 'muted').
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
if style and palette:
|
||||
sns.set_theme(style=style, palette=palette)
|
||||
elif style:
|
||||
sns.set_theme(style=style)
|
||||
elif palette:
|
||||
sns.set_theme(palette=palette)
|
||||
else:
|
||||
sns.set_theme()
|
||||
|
||||
|
||||
def plot_post_steps(
|
||||
fig: matplotlib.figure.Figure,
|
||||
ax: matplotlib.axes.Axes,
|
||||
plt: plt,
|
||||
title: str,
|
||||
x_axis_label: str,
|
||||
y_axis_label: str,
|
||||
x_tick_as_int: bool
|
||||
) -> tuple:
|
||||
r"""Plots a post-processed step plot using Matplotlib.
|
||||
|
||||
Args:
|
||||
fig (matplotlib.figure.Figure): The figure object for the plot.
|
||||
ax (matplotlib.axes.Axes): The axes object for the plot.
|
||||
plt (module): The Matplotlib module.
|
||||
title (str): The title of the plot.
|
||||
x_axis_label (str): The label for the x-axis.
|
||||
y_axis_label (str): The label for the y-axis.
|
||||
x_tick_as_int (bool): If ``True``, use integers for x-axis ticks.
|
||||
For example, if ticks display floating point numbers (e.g., 2002.5),
|
||||
setting this flag forces integer values instead.
|
||||
|
||||
Returns:
|
||||
tuple: A tuple containing the image tensor representation of the plot.
|
||||
"""
|
||||
if x_tick_as_int:
|
||||
ax.xaxis.set_major_locator(mticker.MaxNLocator(integer=True))
|
||||
|
||||
# Set title and labels
|
||||
ax.set_title(title)
|
||||
ax.set_xlabel(x_axis_label)
|
||||
ax.set_ylabel(y_axis_label)
|
||||
|
||||
# Save the plot to a buffer
|
||||
buf = io.BytesIO()
|
||||
fig.savefig(buf, format='PNG')
|
||||
buf.seek(0)
|
||||
plt.close(fig) # Close the figure to free memory
|
||||
|
||||
# Load image and convert to tensor
|
||||
image = Image.open(buf).convert("RGB")
|
||||
image_tensor = torch.from_numpy(np.array(image)).float() / 255.0 # Normalize to [0,1]
|
||||
image_tensor = image_tensor.unsqueeze(0)
|
||||
return (image_tensor,)
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "data-analysis"
|
||||
description = "Data analysis custom modules for ComfyUI - Use Pandas & Matplotlib within ComfyUI"
|
||||
version = "1.1.25"
|
||||
version = "1.2.0"
|
||||
license = {file = "LICENSE"}
|
||||
|
||||
[project.urls]
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
matplotlib>=3.10.0
|
||||
pandas>=2.2.3
|
||||
|
||||
seaborn>=0.13.2
|
||||
scipy>=1.14.1
|
||||
@@ -0,0 +1,38 @@
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
from typing import List
|
||||
|
||||
PROJECT_ROOT = os.path.realpath(os.path.join(__file__, "..", "..", ".."))
|
||||
MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules")
|
||||
sys.path.append(MODULE_ROOT)
|
||||
|
||||
from pandas_wrapper.utils import comma_separated_labels_string_to_list
|
||||
|
||||
class TestCommaSeparatedLabelsStringToList(unittest.TestCase):
|
||||
"""
|
||||
Unit tests for `comma_separated_labels_string_to_list` function.
|
||||
"""
|
||||
|
||||
def setUp(self) -> None:
|
||||
"""
|
||||
Sets up the test environment before each test case.
|
||||
"""
|
||||
pass
|
||||
|
||||
def test_valid_column_strings(self) -> None:
|
||||
"""
|
||||
Tests `comma_separated_labels_string_to_list` with various valid input strings.
|
||||
"""
|
||||
self.assertEqual(comma_separated_labels_string_to_list("label1,label2,label3"), ["label1", "label2", "label3"])
|
||||
self.assertEqual(comma_separated_labels_string_to_list(" label1 , label2 ,label3 "), ["label1", "label2", "label3"])
|
||||
self.assertEqual(comma_separated_labels_string_to_list("a,b,c,d"), ["a", "b", "c", "d"])
|
||||
self.assertEqual(comma_separated_labels_string_to_list("one"), ["one"])
|
||||
self.assertEqual(comma_separated_labels_string_to_list(""), [])
|
||||
self.assertEqual(comma_separated_labels_string_to_list(None), [])
|
||||
self.assertEqual(comma_separated_labels_string_to_list(" , , , "), ["", "", "", ""])
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user