Creating Box-and_Whisker plots
tooprock
I want to display my data by using a Box-Whisker plot. However, I couldn't find a way of calculating and plotting 3 different waves on one graph. When I use the Windows-->New-->Box Plot, it is fine. However, when I want to write a procedure for that I can't show the data on one plot. I use the following codes:
fWavePercentile("F1_W", "10;25;50;75;90", "P_F1", 0, 0, 0) // Calculate the percentiles for first wave
fWavePercentile("F2_W", "10;25;50;75;90", "P_F2", 0, 0, 0) // Do the same for the second wave
fWavePercentile("F3_W", "10;25;50;75;90", "P_F3", 0, 0, 0) // Same for the third wave
then;
fBoxPlot(P_F1_50, P_F1_75, P_F1_25, P_F1_90, P_F1_10, $"", 0.3, 0, $"", $"", 0, 0, 0) // Plot the first values
I don't know how to append the others and also how to modify the appearance of the final plot. Any suggestions?
Thank you so much,
Emre
I was able, with a great deal of effort, to append a new box plot to one I had already made. Here's what I did:
0) I used a text wave as the X wave so that the box plot is a category plot. I don't think it will be easy to do it any other way.
1) I copied the code for the fBoxPlot function to the main procedure window. I renamed the function fAppendBoxPlot and changed "Display" to "AppendToGraph" somewhere around the middle of the function.
2) I made a second independent box plot, being careful to use a different name for the result waves. You have already done that by invoking fWavePercentile with different strings in the first parameter.
3) You will need to make the starting plot using fBoxPlot; I did that just by using the control panel to make the first plot;
4) Use the fAppendBoxPlot function with the starting plot as the top graph. Use the command you use above substituting fAppendBoxPlot for fBoxPlot and "P_F2" for "P_F1" and then again with "P_F3".
5) You now have something of a mess... Double-click any trace to bring up the Modify Trace Appearance dialog.
5a) Find the last trace of the first box plot. Since you aren't using outliers, that would be P_F1_25. Change the Grouping mode to None. Do it for the P_F2_25 trace also. This will make the boxes occupy different slots in the category bar space.
5b) The boxes and median lines are actually X error bars. One by one, select the median traces (P_Fn_50), un-check and re-check the Error Bars checkbox to bring up the Error Bars dialog. Change the X +/- setting to something narrower. Since you will have three boxes, you might choose something like .15. I'm not sure- you will have to experiment.
By now you should have a box plot with three data sets. Since the Graph->Modify Box Plot control panel doesn't expect the extra traces, etc., you can't use it to modify the appearance of the plot. You can use the Modify Trace Appearance dialog to change line thickness and trace color.
Unfortunately, filling the boxes on a box plot is done by adding colored rectangles as drawing objects. It is a royal pain in the neck (or other body part) to do it manually, and the box plot code won't do it correctly in this case. Probably you will have to do without. Maybe you could add colored fills to the error boxes in a drawing program if you export the graph in a suitable format.
I have attached a PNG of the graph I made.
I'm sorry this is so difficult. I will add the capability to my list of things I need to do. Unfortunately, the list is long and dominated by our extensive re-write of Igor for version 7.
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
October 25, 2012 at 09:24 am - Permalink
Thank you so much for your great effort. I can maybe change my question and modify the input that I use, so I won't have to work each data set separately. My new question: What if I have three time series on one graph and analyze them together. I can do it by using the control panel but couldn't find how to do it writing a procedure. I attached one example that I made by using control panel. The main problem is, I don't see any commands on the command window when I use the control panel.
Cheers,
Emre
October 30, 2012 at 04:51 am - Permalink
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
October 30, 2012 at 09:01 am - Permalink
Thank you so much for your help. Unfortunately, I can't send you a copy of the file becuase it is confusing and I am trying to make it clear. Anyway, thank you so much. I'd better use the control panel for this part.
Best,
Emre
November 2, 2012 at 06:56 am - Permalink
then:
- make a category plot of all percentiles
- p10 should be: Marker "-"/ no grouping / black
- p25 should be: sticks to next/ Draw to next / black
- p50 should be: Bar to next / Draw to next / colored
- p75 should be: Bar to next / Draw to next / colored
- p90 should be: stick and marker "-" / Draw to next / black
if needed, reorder the traces (10-25-50-75-90)
this way, I have been able to build the enclosed graph.
I haven't written a procedure to do it automatically, but I guess it is rather simple. Although I used the boxplot package to calculate all the percentiles, I guess it is possible to implement this in a function.
hope this helps someone.
J-E
August 27, 2015 at 03:13 pm - Permalink
The Box Plot procedure uses XY error bars to make the box; that's why they are difficult to fill.
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
August 28, 2015 at 09:19 am - Permalink
Load new data into the data folder.
Select the the ones you want and hit box. The labels button allows you to change the text of the label.
Enjoy.
August 28, 2015 at 10:30 am - Permalink
So is there any chance to see in a near future the possibility to fill box plots directly from the panel? :)
Not vital, but from this manual process, I didn't find the solution to append the average value as a marker...
I wrote some functions to do this manual process automatically on a list of waves to plot.
//-------------------------
Function GlobCatBoxPlot(ListOfMx,ListOfPercentiles,XaxisCatPlot)
wave/S ListofMx,XaxisCatPlot
string ListOfPercentiles
variable i
variable rows=dimsize(ListOfMx,0)
variable nbCat=dimsize(XaxisCatPlot,0)
Make/O/N=(nbCat) NaNWave
NaNWave=NaN
display
AppendToGraph NaNWave vs XaxisCatPlot
for (i=0;i<rows;i+=1)
GraphOneVariable($ListofMx[i],ListOfPercentiles,XaxisCatPlot)
endfor
AppendToGraph NaNWave vs XaxisCatPlot
End Function
//-------------------------
Function CalcMxPerc(Mx,ListOfPercentiles)
wave Mx
string ListOfPercentiles
fWavePercentile(NameOfWave(Mx), ListOfPercentiles, NameOfWave(Mx)+"_p", 0, 0, 0)
wave TempSort,TempMatrix,TmpPercentiles,PCNames
killwaves TempSort,TempMatrix,TmpPercentiles
string temp_str
temp_str=NameOfWave(Mx)+"PCNames"
Rename PCNames $temp_str
temp_str=NameOfWave(Mx)+"_p_N"
killwaves $temp_str
End Function
//-------------------------
Function GraphOneVariable(Mx,ListOfPercentiles,XaxisCatPlot)
wave Mx
string ListOfPercentiles
wave/S XaxisCatPlot
CalcMxPerc(Mx,ListOfPercentiles)
string LowWhiskerW_str=NameOfWave(Mx)+"_p_"+StringFromList(0,ListOfPercentiles)
wave LowWhiskerW=$LowWhiskerW_str
string LowBoxW_str=NameOfWave(Mx)+"_p_"+StringFromList(1,ListOfPercentiles)
wave LowBoxW=$LowBoxW_str
string MedianW_str=NameOfWave(Mx)+"_p_"+StringFromList(2,ListOfPercentiles)
wave MedianW=$MedianW_str
string HighBoxW_str=NameOfWave(Mx)+"_p_"+StringFromList(3,ListOfPercentiles)
wave HighBoxW=$HighBoxW_str
string HighWhiskerW_str=NameOfWave(Mx)+"_p_"+StringFromList(4,ListOfPercentiles)
wave HighWhiskerW=$HighWhiskerW_str
AppendToGraph HighWhiskerW, HighBoxW, MedianW,LowBoxW, LowWhiskerW vs XaxisCatPlot
ModifyGraph mode($LowWhiskerW_str)=3,marker($LowWhiskerW_str)=9,rgb($LowWhiskerW_str)=(0,0,0)
ModifyGraph mode($LowBoxW_str)=1,toMode($LowBoxW_str)=1,rgb($LowBoxW_str)=(0,0,0)
ModifyGraph hbFill($MedianW_str)=2,toMode($MedianW_str)=1,useBarStrokeRGB($MedianW_str)=1
ModifyGraph hbFill($HighBoxW_str)=2,toMode($HighBoxW_str)=1,useBarStrokeRGB($HighBoxW_str)=1
ModifyGraph mode($HighWhiskerW_str)=8,marker($HighWhiskerW_str)=9,toMode($HighWhiskerW_str)=1, rgb($HighWhiskerW_str)=(0,0,0)
End Function
it necessarily uses 5 percentiles to build the boxplot... maybe it'd help
August 30, 2015 at 06:03 am - Permalink
I always encounter 'got 's_name' instead of a string variable or string function name' error when try to compile the fAppendBoxPlot function after changing 'Display' to 'AppendToGraph'. What could be the problem? Thank you!
September 30, 2015 at 03:48 pm - Permalink