Skip to main content
Glama

mpl_mcp_plot_stem

Create stem charts to visualize discrete data points with connecting lines to a baseline. Input x and y data arrays to generate customizable plots with labels, titles, colors, and formatting options.

Instructions

Plots stem chart of given datavalues

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
x_dataYes
y_dataYes
labelsNo
titleNo
xlabelNo
ylabelNo
colorsNoblue
linefmtNo-
markerfmtNoo
basefmtNok-
bottomNo
orientationNovertical
dpiNo
figsizeNo
gridNo
legendNo

Implementation Reference

  • The main handler function `plot_stem` that generates stem plots using matplotlib's stem function, supports multiple series, vertical/horizontal orientation, and returns a PNG image.
    def plot_stem(
        x_data: Union[List[Union[float, int]], List[List[Union[float, int]]]],
        y_data: Union[List[Union[float, int]], List[List[Union[float, int]]]],
        labels: Optional[Union[str, List[str]]] = None,
        title: str = "",
        xlabel: str = "",
        ylabel: str = "",
        colors: Union[str, List[str]] = "blue",
        linefmt: str = "-",
        markerfmt: str = "o",
        basefmt: str = "k-",
        bottom: float = 0.0,
        orientation: str = "vertical",  # "vertical" or "horizontal"
        dpi: int = 200,
        figsize: Optional[List[Union[int, float]]] = None,
        grid: bool = True,
        legend: bool = False,
    ) -> Image:
        """
        Create a stem plot (vertical or horizontal) with customizable appearance.
    
        Args:
            x_data: X-axis data points (1D array-like)
            y_data: Y-axis data points (1D or 2D array-like for multiple series)
            labels: Label or list of labels for the data series
            title: Plot title
            xlabel: Label for the x-axis
            ylabel: Label for the y-axis
            colors: Color or list of colors for the stems and markers
            linefmt: Line style for the stems (default: "-" for solid line)
            markerfmt: Marker style for the points (default: "o" for circles)
            basefmt: Format of the baseline (default: "k-" for black line)
            bottom: Position of the baseline (default: 0.0)
            orientation: "vertical" or "horizontal" (default: "vertical")
            dpi: Output image resolution (dots per inch, default: 200)
            figsize: Figure size as (width, height) in inches.
            grid: Whether to show grid lines (default: True)
            legend: Whether to show legend (default: False)
    
        Returns:
            FastMCP Image object with the plotted stem chart
        """
        # Convert inputs to numpy arrays with explicit float type
        x = np.asarray(x_data, dtype=float)
        y = np.asarray(y_data, dtype=float)
    
        # Handle 1D y_data case by adding an extra dimension
        if y.ndim == 1:
            y = y.reshape(1, -1)
    
        # Ensure x matches the number of data points in y
        if x.ndim == 1 and len(x) != y.shape[1]:
            x = np.tile(x, (y.shape[0], 1))
    
        # Handle labels — normalize to a list
        if labels is None:
            labels_list: List[str] = [""] * y.shape[0]
        elif isinstance(labels, str):
            labels_list = [labels]
        else:
            labels_list = list(labels)
    
        # Handle colors — normalize to a list
        if isinstance(colors, str):
            colors_list = [colors] * y.shape[0]
        else:
            colors_list = list(colors)
    
        # Create figure with specified size using OO interface
        # Normalize figsize
        if figsize and len(figsize) >= 2:
            figsize_vals = (float(figsize[0]), float(figsize[1]))
        else:
            figsize_vals = (6.0, 4.0)
    
        fig, ax = plt.subplots(figsize=figsize_vals, dpi=dpi)
    
        # Create the stem plot for each series
        # Create the stem plot for each series
        for i in range(y.shape[0]):
            current_label = labels_list[i] if i < len(labels_list) else f"Series {i+1}"
            current_color = colors_list[i % len(colors_list)]
    
            # Create the stem plot
            if orientation == "vertical":
                markerline, stemlines, baseline = ax.stem(
                    x[i] if x.ndim > 1 else x,
                    y[i],
                    linefmt=linefmt,
                    markerfmt=markerfmt,
                    basefmt=basefmt,
                    bottom=bottom,
                    label=current_label,
                )
            else:  # horizontal
                markerline, stemlines, baseline = ax.stem(
                    y[i],
                    x[i] if x.ndim > 1 else x,
                    linefmt=linefmt,
                    markerfmt=markerfmt,
                    basefmt=basefmt,
                    bottom=bottom,
                    label=current_label,
                    orientation="horizontal",
                )
    
            # Set the color for this series
            plt.setp(stemlines, "color", current_color)
            plt.setp(markerline, "color", current_color)
            plt.setp(baseline, "color", "black")
    
        # Customize the plot
        ax.set_title(title)
        ax.set_xlabel(xlabel if orientation == "vertical" else ylabel)
        ax.set_ylabel(ylabel if orientation == "vertical" else xlabel)
    
        if grid:
            ax.grid(True, linestyle="--", alpha=0.7)
    
        if legend and any(labels_list):
            ax.legend()
    
        # Save the plot to a buffer and close the figure
        buf = io.BytesIO()
        fig.savefig(buf, format="png", dpi=dpi, bbox_inches="tight")
        plt.close(fig)
        buf.seek(0)
    
        return Image(data=buf.read(), format="png")
  • Registers the `plot_stem` function as an MCP tool under the name `mpl_mcp_plot_stem` using FastMCP's tool decorator.
    mpl_mcp.tool(plot_stem, description="Plots stem chart of given datavalues")
  • The function signature with type annotations defines the input schema and output type for the tool.
    def plot_stem(
        x_data: Union[List[Union[float, int]], List[List[Union[float, int]]]],
        y_data: Union[List[Union[float, int]], List[List[Union[float, int]]]],
        labels: Optional[Union[str, List[str]]] = None,
        title: str = "",
        xlabel: str = "",
        ylabel: str = "",
        colors: Union[str, List[str]] = "blue",
        linefmt: str = "-",
        markerfmt: str = "o",
        basefmt: str = "k-",
        bottom: float = 0.0,
        orientation: str = "vertical",  # "vertical" or "horizontal"
        dpi: int = 200,
        figsize: Optional[List[Union[int, float]]] = None,
        grid: bool = True,
        legend: bool = False,
    ) -> Image:
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden for behavioral disclosure but provides none. It doesn't mention that this creates a visualization output, what format it returns (image file? display?), whether it has side effects, or any performance considerations. The description only states what it does, not how it behaves.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise - a single 6-word sentence. While this is efficient, it's arguably under-specified given the tool's complexity. However, it's front-loaded with the core purpose and contains no wasted words, earning a high conciseness score despite the content being insufficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex plotting tool with 16 parameters, no annotations, no output schema, and 0% schema description coverage, the description is completely inadequate. It doesn't explain what the tool returns, how to interpret parameters, when to use it, or any behavioral characteristics. The description fails to provide the context needed for effective tool selection and invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 16 parameters and 0% schema description coverage, the description provides no parameter information beyond the tool name. The schema has titles like 'X Data' and 'Y Data' but no descriptions. The tool description doesn't explain what x_data and y_data represent, what formats are acceptable, or how the 14 optional parameters affect the visualization.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Plots stem chart of given datavalues' clearly states the verb ('plots') and resource ('stem chart'), but it's vague about what a stem chart is and doesn't differentiate from sibling plotting tools like mpl_mcp_plot_barchart or mpl_mcp_plot_scatter. It provides basic purpose but lacks specificity about the visualization type.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. With multiple sibling plotting tools (barchart, scatter, stack, etc.), there's no indication of when a stem chart is appropriate versus other visualization types. No usage context, prerequisites, or exclusions are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/abhiphile/fermat-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server