VIOLIN
Excel Usage
=VIOLIN(data, title, xlabel, ylabel, stat_color, vert, medians, grid)
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.stat_color(str, optional, default: null): Violin color.vert(str, optional, default: “true”): Orientation (‘true’ for vertical, ‘false’ for horizontal).medians(str, optional, default: “true”): Show medians.grid(str, optional, default: “true”): Show grid lines.
Returns (object): Matplotlib Figure object (standard Python) or base64 encoded PNG string (Pyodide).
Examples
Example 1: Violin plot with single distribution
Inputs:
| data |
|---|
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
Excel formula:
=VIOLIN({1;2;3;4;5;6;7;8;9;10})
Expected output:
"chart"
Example 2: Violin plot with multiple distributions
Inputs:
| data | ||
|---|---|---|
| 1 | 10 | 100 |
| 2 | 20 | 200 |
| 3 | 30 | 300 |
| 4 | 40 | 400 |
| 5 | 50 | 500 |
Excel formula:
=VIOLIN({1,10,100;2,20,200;3,30,300;4,40,400;5,50,500})
Expected output:
"chart"
Example 3: Horizontal violin plot with labels
Inputs:
| data | vert | title | xlabel | ylabel |
|---|---|---|---|---|
| 1 | false | Test Violin | Value | Group |
| 2 | ||||
| 3 | ||||
| 4 | ||||
| 5 | ||||
| 6 | ||||
| 7 |
Excel formula:
=VIOLIN({1;2;3;4;5;6;7}, "false", "Test Violin", "Value", "Group")
Expected output:
"chart"
Example 4: Violin plot without medians
Inputs:
| data | medians |
|---|---|
| 1 | false |
| 2 | |
| 3 | |
| 4 | |
| 5 |
Excel formula:
=VIOLIN({1;2;3;4;5}, "false")
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 violin(data, title=None, xlabel=None, ylabel=None, stat_color=None, vert='true', medians='true', grid='true'):
"""
Create a violin plot from data.
See: https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.violinplot.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.
stat_color (str, optional): Violin color. Valid options: Blue, Green, Red, Cyan, Magenta, Yellow, Black, White. Default is None.
vert (str, optional): Orientation ('true' for vertical, 'false' for horizontal). Valid options: True, False. Default is 'true'.
medians (str, optional): Show medians. Valid options: True, False. Default is 'true'.
grid (str, optional): Show grid lines. Valid options: True, False. Default is 'true'.
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
def str_to_bool(s):
return s.lower() == "true" if isinstance(s, str) else bool(s)
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 numeric columns
cols = []
max_rows = max(len(row) for row in data) if data else 0
for col_idx in range(max_rows):
col_data = []
for row in data:
if col_idx < len(row):
val = row[col_idx]
try:
col_data.append(float(val))
except (TypeError, ValueError):
continue
if col_data:
cols.append(col_data)
if not cols:
return "Error: No valid numeric data found"
# Create plot
fig, ax = plt.subplots(figsize=(8, 6))
# Plot violin
parts = ax.violinplot(cols, vert=str_to_bool(vert),
showmedians=str_to_bool(medians))
# Set color
if stat_color:
for pc in parts['bodies']:
pc.set_facecolor(stat_color)
pc.set_alpha(0.7)
if title:
ax.set_title(title)
if xlabel:
ax.set_xlabel(xlabel)
if ylabel:
ax.set_ylabel(ylabel)
if str_to_bool(grid):
ax.grid(True, alpha=0.3)
plt.tight_layout()
# Return based on platform
if IS_PYODIDE:
buf = io.BytesIO()
plt.savefig(buf, format='png', dpi=100, bbox_inches='tight')
buf.seek(0)
img_base64 = base64.b64encode(buf.read()).decode('utf-8')
plt.close(fig)
return f"data:image/png;base64,{img_base64}"
else:
return fig
except Exception as e:
return f"Error: {str(e)}"