views:

890

answers:

3

I would like to plot a vertical line (I'd prefer any orientation, but I'd be happy with just vertical right now) with two-color dashes, say red-blue-red-blue-...

I know I could do it like this:

plot([1,1],[0,1],'r'),
hold on,
plot([1,1],[0,1],'--b')

However, since I need to be able to move the line, among others, it should only have a single handle. How could I do this?

EDIT Thank you for your answers. I guess I should indeed give some more information.

I have some data that is classified into different parts. I want to be able to manually adjust the boundaries between classes. For this, I'm drawing vertical lines at the classification boundaries and use draggable to allow moving the lines.

For the boundary between the red and the blue class, I'd like to have a red/blue line.

plot(ones(10,1),linspace(0,1,10),'-bs','MarkerFaceColor','r','MarkerEdgeColor','none','linewidth',6)

is what I'm actually using at the moment. However, it's not so pretty (if I want equal spacing, it becomes a real pain, and I want to give both colors the same weight), and I would like to have the possibility to use three colors (and not with marker edge and face being different, because it makes my eyes bleed).

Unfortunately, draggable does not allow me to use multiple handles, and grouping the lines with hggroup does not seem to create a draggable object.

cline looks like a promising approach, but rainbow colors won't work for my application.

A: 

I don't know how to do exactly what you want, but presumably the reason you want to do this is to have some way of distinguishing this line from other lines. Along those lines, take a look at MathWorks' documentation on 2-D line plots. Specifically, this example:

plot(x,y,'--rs','LineWidth',2,...
                'MarkerEdgeColor','k',...
                'MarkerFaceColor','g',...
                'MarkerSize',10)

should give you plenty of ideas for variation. If you really need the two-color dashes, it might help to specify why. That way, even if we can't answer the question, perhaps we can convince you that you don't really need the two-color dashes. Since you've already ruled out the over-lapping solution, I'm fairly certain there's no solution that answers all of your needs. I'm assuming the two-colorness is the most fluid of those needs.

Ben Hocking
As it turns out, I have actually read the manual first (though I admit I should have mentioned that), and I do really want the two-colorness.
Jonas
+2  A: 

I've never used it, but there's a submission by Sebastian Hölz called CLINE on the Mathworks File Exchange that seems related.

mtrw
That's almost what I need. At any rate, it's nice to know that cline exists.
Jonas
+3  A: 

You can use the code you have, and just concatenate the handles from each line into a vector of handles. When you want to change the properties of both lines simultaneously, the SET function is able to accept the vector of handles as an argument. From the documentation for SET:

set(H,'PropertyName',PropertyValue,...) sets the named properties to the specified values on the object(s) identified by H. H can be a vector of handles, in which case set sets the properties' values for all the objects.

Here's an example:

h1 = plot([1 1],[0 1],'r');    %# Plot line 1
hold on;
h2 = plot([1 1],[0 1],'--b');  %# Plot line 2
hVector = [h1 h2];             %# Vector of handles
set(hVector,'XData',[2 3]);    %# Shifts the x data points for both lines



UPDATE: Since you mention you are using draggable from the MathWorks File Exchange, here's an alternate solution. From the description of draggable:

A function which is called when the object is moved can be provided as an optional argument, so that the movement triggers further actions.

You could then try the following solution:

  • Plot your two lines, saving the handle for each (i.e. h1 and h2).
  • Put the handle for each in the 'UserData' property of the other:

    set(h1,'UserData',h2);
    set(h2,'UserData',h1);
    
  • Create the following function:

    function motionFcn(hMoving)  %# Currently moving handle is passed in
      hOther = get(hMoving,'UserData');  %# Get the other plot handle
      set(hOther,'XData',get(hMoving,'XData'),...  %# Update the x data
                 'YData',get(hMoving,'YData'));    %# Update the y data
    end
    
  • Turn on draggable for both lines, using the above function as the one called when either object is moved:

    draggable(h1,@motionFcn);
    draggable(h2,@motionFcn);
    
gnovice
Yes, I'd like to be able to do that. Unfortunately, it doesn't seem to work for my application (see edit).
Jonas
@Jonas: I added an additional solution to my answer that I think should work with draggable.
gnovice
Thanks! This works very nicely. I need to use setappdata/getappdata, because I already use UserData, though.
Jonas
@Jonas: Glad it worked for you. Incidentally, I couldn't actually test the solution because draggable doesn't seem to work with my version of MATLAB (7.8.0 R2009a). Maybe something in the newer versions breaks it, seeing as how it was written for version 6.5 (R13).
gnovice
@gnovice: draggable works fine for me with 2009a on OS X. However, you cannot drag the line outside the axes boundaries, so you should plot either a horizontal or vertical, not a diagonal line. :)
Jonas
@Jonas: Yeah, that was the problem. I didn't notice you had switched the example in the question to a vertical line. Works fine now! ;)
gnovice

related questions