SEMILOGY

Excel Usage

=SEMILOGY(data, title, xlabel, ylabel, plot_color, linestyle, marker, legend)
  • data (list[list], required): Input data.
  • title (str, optional, default: null): Chart title.
  • xlabel (str, optional, default: null): Label for X-axis.
  • ylabel (str, optional, default: null): Label for Y-axis.
  • plot_color (str, optional, default: null): Line color.
  • linestyle (str, optional, default: “-”): Line style.
  • marker (str, optional, default: null): Marker style.
  • legend (str, optional, default: “false”): Show legend.

Returns (object): Matplotlib Figure object (standard Python) or base64 encoded PNG string (Pyodide).

Examples

Example 1: Basic semi-log Y plot

Inputs:

data
1 1
2 10
3 100
4 1000

Excel formula:

=SEMILOGY({1,1;2,10;3,100;4,1000})

Expected output:

"chart"

Example 2: Semi-log Y with multiple series

Inputs:

data legend
1 1 2 true
2 10 20
3 100 200

Excel formula:

=SEMILOGY({1,1,2;2,10,20;3,100,200}, "true")

Expected output:

"chart"

Example 3: Semi-log Y with markers and color

Inputs:

data plot_color marker
0 1 green ^
1 10
2 100
3 1000

Excel formula:

=SEMILOGY({0,1;1,10;2,100;3,1000}, "green", "^")

Expected output:

"chart"

Example 4: Semi-log Y with labels and title

Inputs:

data title xlabel ylabel
1 1 Semi-log Y X Y (log)
2 10
3 100
4 1000

Excel formula:

=SEMILOGY({1,1;2,10;3,100;4,1000}, "Semi-log Y", "X", "Y (log)")

Expected output:

"chart"

Python Code

import sys
import matplotlib
IS_PYODIDE = sys.platform == "emscripten"
if IS_PYODIDE:
    matplotlib.use('Agg')
import matplotlib.pyplot as plt
import io
import base64
import numpy as np

def semilogy(data, title=None, xlabel=None, ylabel=None, plot_color=None, linestyle='-', marker=None, legend='false'):
    """
    Create a plot with a log-scale Y-axis.

    See: https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.semilogy.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        data (list[list]): Input data.
        title (str, optional): Chart title. Default is None.
        xlabel (str, optional): Label for X-axis. Default is None.
        ylabel (str, optional): Label for Y-axis. Default is None.
        plot_color (str, optional): Line color. Valid options: Blue, Green, Red, Cyan, Magenta, Yellow, Black, White. Default is None.
        linestyle (str, optional): Line style. Valid options: Solid, Dashed, Dotted, Dash-dot. Default is '-'.
        marker (str, optional): Marker style. Valid options: None, Point, Pixel, Circle, Square, Triangle Down, Triangle Up. Default is None.
        legend (str, optional): Show legend. Valid options: True, False. Default is 'false'.

    Returns:
        object: Matplotlib Figure object (standard Python) or base64 encoded PNG string (Pyodide).
    """
    def to2d(x):
        return [[x]] if not isinstance(x, list) else x

    try:
        data = to2d(data)

        if not isinstance(data, list) or not all(isinstance(row, list) for row in data):
            return "Error: Invalid input - data must be a 2D list"

        # Extract X and Y columns
        if len(data) < 1 or len(data[0]) < 2:
            return "Error: Data must have at least 2 columns"

        # Determine number of series (first column is X, rest are Y series)
        num_series = len(data[0]) - 1

        X = []
        Y_series = [[] for _ in range(num_series)]

        for row in data:
            if len(row) >= 2:
                try:
                    x_val = float(row[0])
                    X.append(x_val)
                    for i in range(num_series):
                        if i + 1 < len(row):
                            try:
                                y_val = float(row[i + 1])
                                if y_val > 0:  # Log scale requires positive values
                                    Y_series[i].append(y_val)
                                else:
                                    Y_series[i].append(None)
                            except (TypeError, ValueError):
                                Y_series[i].append(None)
                        else:
                            Y_series[i].append(None)
                except (TypeError, ValueError):
                    continue

        if len(X) == 0:
            return "Error: No valid X values found"

        # Check if we have any valid Y values
        has_valid_y = any(any(y is not None for y in Y) for Y in Y_series)
        if not has_valid_y:
            return "Error: No valid positive Y values found"

        # Create semilogy plot
        fig, ax = plt.subplots(figsize=(8, 6))

        # Plot each series
        for i, Y in enumerate(Y_series):
            plot_kwargs = {'linestyle': linestyle}
            if plot_color:
                plot_kwargs['color'] = plot_color
            if marker:
                plot_kwargs['marker'] = marker

            # Filter out None values
            X_filtered = [X[j] for j in range(len(X)) if j < len(Y) and Y[j] is not None]
            Y_filtered = [y for y in Y if y is not None]

            if len(X_filtered) > 0:
                ax.semilogy(X_filtered, Y_filtered, label=f"Series {i+1}", **plot_kwargs)

        if title:
            ax.set_title(title)
        if xlabel:
            ax.set_xlabel(xlabel)
        if ylabel:
            ax.set_ylabel(ylabel)

        if legend == "true" and num_series > 1:
            ax.legend()

        ax.grid(True, which="both", ls="-", alpha=0.2)

        if IS_PYODIDE:
            buf = io.BytesIO()
            plt.savefig(buf, format='png', bbox_inches='tight')
            plt.close(fig)
            buf.seek(0)
            img_base64 = base64.b64encode(buf.read()).decode('utf-8')
            return f"data:image/png;base64,{img_base64}"
        else:
            return fig
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator