diff --git a/__init__.py b/__init__.py index d15761f..acea2cf 100644 --- a/__init__.py +++ b/__init__.py @@ -106,6 +106,7 @@ 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_histogram import SNSHistogram from .modules.seaborn_wrapper.sns_line import SNSLine from .modules.seaborn_wrapper.sns_scatter import SNSScatter T = TypeVar("T") @@ -223,6 +224,7 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = { "PandasVerticalSplit": PandasVerticalSplit, "PandasXs": PandasXs, "SNSBar": SNSBar, + "SNSHistogram": SNSHistogram, "SNSLine": SNSLine, "SNSScatter": SNSScatter, } @@ -340,6 +342,7 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = { "PandasVerticalSplit": "Pandas Vertical Split", "PandasXs": "Pandas Xs", "SNSBar": "SNS Bar Chart", + "SNSHistogram": "SNS Histogram", "SNSLine": "SNS Line Plot", "SNSScatter": "SNS Scatter Plot", } diff --git a/docs/reference/node_reference.md b/docs/reference/node_reference.md index ea18e87..4b4c78f 100644 --- a/docs/reference/node_reference.md +++ b/docs/reference/node_reference.md @@ -115,6 +115,7 @@ | [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 Histogram](sns_histogram.md) | Generates a histogram 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 diff --git a/docs/reference/sns_histogram.md b/docs/reference/sns_histogram.md new file mode 100644 index 0000000..fa0ad71 --- /dev/null +++ b/docs/reference/sns_histogram.md @@ -0,0 +1,14 @@ +# SNS Histogram +Generates a histogram from a Pandas DataFrame using Seaborn. + +For style and palette parameters, refer to [SNS Line Plot documentation](sns_line.md). + +## Output +| Data type | +|---| +| Image | + +
+Category: Plot + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/modules/seaborn_wrapper/common.py b/modules/seaborn_wrapper/common.py index 7212d2c..27ccf2b 100644 --- a/modules/seaborn_wrapper/common.py +++ b/modules/seaborn_wrapper/common.py @@ -19,3 +19,24 @@ def common_input_types(): "palette": ("STRING", {"default": ""}) } } + +def common_input_types_y_only_bin(): + """ + Defines the input types for a plot function for types of charts that do + not require x-series data as input, but takes bins. + + Returns: + Dict[str, Any]: A dictionary specifying required input types. + """ + return { + "required": { + "dataframe": ("DATAFRAME", {}), + "y_column_name": ("STRING", {"default": ""}), + "title": ("STRING", {"default": ""}), + "y_axis_label": ("STRING", {"default": ""}), + # "legend_label": ("STRING", {"default": ""}), + "bins": ("INT", {"default": 10, "min": 2, "max": 200}), + "style": ("STRING", {"default": ""}), + "palette": ("STRING", {"default": ""}) + } + } diff --git a/modules/seaborn_wrapper/sns_histogram.py b/modules/seaborn_wrapper/sns_histogram.py new file mode 100644 index 0000000..5f8038f --- /dev/null +++ b/modules/seaborn_wrapper/sns_histogram.py @@ -0,0 +1,78 @@ +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_y_only_bin +from .util import plot_post_steps +from .util import set_up_sns_style_palette +from .util import process_y_columns_and_labels + + +class SNSHistogram: + """ + SNS Histogram: + Generates a histogram from a Pandas DataFrame using Seaborn. + + Currently, plotting multiple series of data is not supported. + 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_y_only_bin() + + RETURN_TYPES: tuple = ("IMAGE",) + FUNCTION: str = "bar_chart" + CATEGORY: str = "Data Analysis" + + def bar_chart(self, + dataframe: pd.DataFrame, + y_column_name: str, + title: str, + y_axis_label: str, + # legend_label: str, + bins: int, + style: str=None, + palette: str=None) -> tuple: + """ + Generates a bar chart from a pandas DataFrame. + + Args: + dataframe (DataFrame): The DataFrame. + y_column_name (str): The column name for the y-axis. + title (str): The title of the plot. + y_axis_label (str): The label for the y-axis data. + bins (int): Number of bins. + 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) + + # TODO: For future enhancement, restore legend_label as the last arg. + y_columns, labels = process_y_columns_and_labels(df, y_column_name, "") + + # Create the plot + fig, ax = plt.subplots() + for i in range(len(y_columns)): + sns.histplot(df[y_columns[i]], bins=bins, ax=ax, label=labels[i]) + break # TODO: Remove this if we decide support multiple plots + + return plot_post_steps( + fig, + ax, + plt, + title, + None, + y_axis_label, + None) diff --git a/modules/seaborn_wrapper/util.py b/modules/seaborn_wrapper/util.py index 54396cd..69b8164 100644 --- a/modules/seaborn_wrapper/util.py +++ b/modules/seaborn_wrapper/util.py @@ -90,7 +90,8 @@ def plot_post_steps( # Set title and labels ax.set_title(title) - ax.set_xlabel(x_axis_label) + if x_axis_label: + ax.set_xlabel(x_axis_label) ax.set_ylabel(y_axis_label) # Save the plot to a buffer diff --git a/pyproject.toml b/pyproject.toml index a300e76..a8eb900 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "data-analysis" description = "Data analysis custom modules for ComfyUI - Use Pandas & Matplotlib within ComfyUI" -version = "1.2.0" +version = "1.2.1" license = {file = "LICENSE"} [project.urls]