You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于Gnuplot绘制小提琴图报错:所有点y值未定义求助

Fixing "all points y value undefined!" in Gnuplot Violin Plot

Let's break down what's causing your error and walk through fixing it step by step.

Key Issues Identified

  1. Too-small bandwidth for kernel density: Your data ranges from hundreds to thousands of milliseconds, but you're using a bandwidth of 10. This is way too narrow—gnuplot can't compute a meaningful density curve, resulting in an empty $kdensity1 dataset.
  2. Incorrect filledcurves syntax: The filledcurve x=1 syntax isn't valid for your use case, and it's contributing to plotting failures.
  3. Mismatched axis ranges: Your xrange [-6:6] is overly broad, and missing a defined yrange can lead to gnuplot filtering out valid points accidentally.

Corrected Script

Here's a revised version of your script with fixes and explanations:

reset
set terminal pdfcairo size 20,14 enhanced font 'Times,28'
set output 'violinplot.0.pdf'
set datafile separator ','

# Generate kernel density data for column 2 (adjust bandwidth to match your data)
set table $kdensity1
# Using 2:1 sets x to your time data, y=1 is a dummy value to trigger density calculation
plot 'profile.csv' using 2:1 smooth kdensity bandwidth 200
unset table

# Uncomment to debug: verify $kdensity1 has data
# print $kdensity1

unset key
set border 2
set ytics nomirror rangelimited
set title "Distribution of times in milliseconds"
set style fill solid 0.7 bo -1  # Add slight transparency for better readability

# Set sensible axis ranges
set xrange [0:2]  # Fits violin centered at x=1 with room for width
set yrange [0:*]  # Auto-scale y to include all time data

# Plot violin: draw left/right density curves, then fill the area between them
plot $kdensity1 using (1 + $2*1000):1 with curve lt 10, \
     '' using (1 - $2*1000):1 with curve lt 10, \
     '' using (1 + $2*1000):1 with filledcurves x1 lt 10

What Changed & Why

  • Increased bandwidth to 200: This matches the scale of your millisecond data, ensuring gnuplot computes a valid, smooth density curve. Adjust this value up/down if your violin looks too narrow or too wide.
  • Scaled density values: Multiplying $2 (the density value) by 1000 amplifies the x-axis offset, making the violin's width visible. Tweak this factor to get your desired violin thickness.
  • Fixed filledcurves syntax: filledcurves x1 tells gnuplot to fill the area between the first and second plotted curves (your left/right density lines).
  • Restricted xrange: A range of [0:2] keeps the violin centered at x=1 without wasting space, ensuring all valid points are included.
  • Explicit yrange: [0:*] ensures all your time data is visible, preventing gnuplot from auto-scaling to an empty dataset.

Extending to Multiple Columns

If you want to plot violins for columns 3-6 (each at x=2,3,4,5), repeat the density generation step for each column and add their plots:

# Example for column 3 (smaller values, use smaller bandwidth)
set table $kdensity2
plot 'profile.csv' using 3:1 smooth kdensity bandwidth 50
unset table

# Add to your plot command:
$kdensity2 using (2 + $2*1000):1 with curve lt 11, \
'' using (2 - $2*1000):1 with curve lt 11, \
'' using (2 + $2*1000):1 with filledcurves x1 lt 11

Debugging Tips

  • Always uncomment print $kdensity1 first to confirm gnuplot is generating density data. If it's empty, your bandwidth is still too small or your data path/separator is incorrect.
  • Start with a larger bandwidth and adjust down until you get the desired smoothness for your violin.

内容的提问来源于stack exchange,提问作者Nicola

火山引擎 最新活动