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)}"