Re: Legend for plot [message #67975] |
Tue, 15 September 2009 22:49  |
b.a
Messages: 26 Registered: July 2009
|
Junior Member |
|
|
What I mean, is to have the plot (and oplots) and the legend inside
one window in my GUI. Actually my interface has several parts and one
is a widget draw that will contain all the curves to be plotted. The
problem is that when each curve is plotted, even though they have
different colours, it is not clear which one is which. So I have to
place a legend in there. I can't really use XYOUTS because I might
have several plots which interrupt each other and I don't know where
to place the XYOUTS :(
Is it at all possible to place a legend inside a widget_draw which
contains plots? The code that you wrote is what I want plus I need to
put the plots in the same window.
Thanks a lot.
|
|
|
Re: Legend for plot [message #67978 is a reply to message #67975] |
Tue, 15 September 2009 21:40   |
penteado
Messages: 866 Registered: February 2018
|
Senior Member Administrator |
|
|
On Sep 16, 1:19 am, pp <pp.pente...@gmail.com> wrote:
> The third window is created by your call to plot. Plot is a direct
> graphics routine, so it cannot draw on your widget_draw. You must put
> object graphics in your view object, as you did with the legend. For a
> plot, it usually means making and setting up a bunch of them (plots,
> axes, titles, symbols). I usually prefer to make an invisible iplot
> and borrow its view object, so that iplot does all the work of making
> and setting up the objects in the plot.
>
I was just looking at your original post. I was assuming what you
wanted to know was how to put object graphics (the legend object, in
that case) into a draw widget, and that is what I was talking about.
But it just occurred to me that the original question might have been
just how to put a legend into a direct graphics draw widget, which
should not (cannot) be done with the object legend you were trying to
use, it should be done with xyouts. Which one is it that you wanted?
|
|
|
Re: Legend for plot [message #67979 is a reply to message #67978] |
Tue, 15 September 2009 21:19   |
penteado
Messages: 866 Registered: February 2018
|
Senior Member Administrator |
|
|
On Sep 15, 9:58 pm, "b.a" <u4565...@anu.edu.au> wrote:
> Thanks for your solution. But I couldn't get it to work. What happens
> now, is that I get 3 separate window: one for my GUI (a simple tlb and
> draw widget), one for the legend (but the legend doesn't appear in it)
> and one for my plots.
The first empty one is because you are making an empty window object
(in mywindow = OBJ_NEW('IDLgrWindow')), and as such it will show up on
its own, not in your draw widget. Remove that line. The window object
you want is the one in the draw widget.
> as you see, I have commented this line:
> ;mywindow->Draw, myview
>
> If I don't do that, it gives error:
> Unable to invoke method on NULL object reference: <OBJREF
> (<NullObject>)>.
> ehich I think means that mywindow is a null object.
Sorry, forgot to say that the widget must be realized before you ask
for the
window object. That is why it was null at that point.
The third window is created by your call to plot. Plot is a direct
graphics routine, so it cannot draw on your widget_draw. You must put
object graphics in your view object, as you did with the legend. For a
plot, it usually means making and setting up a bunch of them (plots,
axes, titles, symbols). I usually prefer to make an invisible iplot
and borrow its view object, so that iplot does all the work of making
and setting up the objects in the plot.
Without getting into how to make the plots, your code would work as
pro demolegend
x1 = [1,2,3,4,5]
y1 = [4,5,6,7,8]
x2 = [2,3,4,4.5,5]
y2 = [4,5,6,7,8]
tlb = Widget_Base(column=1, XSIZE=350, YSIZE= 400,$
XOFFSET=250, YOFFSET= 300)
dr_window = WIDGET_DRAW(tlb, UVALUE= 'draw', $
XSIZE= 348, YSIZE=200, GRAPHICS_LEVEL = 2)
myview = OBJ_NEW('IDLgrView')
itemNameArr = ['One', 'two']
myLegend = OBJ_NEW('IDLgrLegend', itemNameArr)
myview->Add, mylegend
Widget_Control, tlb, /realize
WIDGET_CONTROL, dr_window, GET_VALUE = mywindow
mywindow->Draw, myview
;plot, y2, x2, COLOR= 40, BACKGROUND= 255
;oplot, y1, x1, COLOR= 80
Xmanager, 'demolegend', tlb
end
|
|
|
Re: Legend for plot [message #67981 is a reply to message #67979] |
Tue, 15 September 2009 17:58   |
b.a
Messages: 26 Registered: July 2009
|
Junior Member |
|
|
Thanks for your solution. But I couldn't get it to work. What happens
now, is that I get 3 separate window: one for my GUI (a simple tlb and
draw widget), one for the legend (but the legend doesn't appear in it)
and one for my plots.
Here is the code that I tried:
----------------------------------------------------
pro demolegend
x1 = [1,2,3,4,5]
y1 = [4,5,6,7,8]
x2 = [2,3,4,4.5,5]
y2 = [4,5,6,7,8]
tlb = Widget_Base(column=1, XSIZE=350, YSIZE= 400,$
XOFFSET=250, YOFFSET= 300)
dr_window = WIDGET_DRAW(tlb, UVALUE= 'draw', $
XSIZE= 348, YSIZE=200, GRAPHICS_LEVEL = 2)
mywindow = OBJ_NEW('IDLgrWindow')
myview = OBJ_NEW('IDLgrView')
itemNameArr = ['One', 'two']
myLegend = OBJ_NEW('IDLgrLegend', itemNameArr)
myview->Add, mylegend
WIDGET_CONTROL, dr_window, GET_VALUE = mywindow
;mywindow->Draw, myview
Widget_Control, tlb, /realize
plot, y2, x2, COLOR= 40, BACKGROUND= 255
oplot, y1, x1, COLOR= 80
Xmanager, 'demolegend', tlb
end
------------------------------------------------------------ ----------
as you see, I have commented this line:
;mywindow->Draw, myview
If I don't do that, it gives error:
Unable to invoke method on NULL object reference: <OBJREF
(<NullObject>)>.
ehich I think means that mywindow is a null object.
Can you think of any solution for this?
Thank you
|
|
|
Re: Legend for plot [message #67999 is a reply to message #67981] |
Fri, 11 September 2009 08:42   |
penteado
Messages: 866 Registered: February 2018
|
Senior Member Administrator |
|
|
On Sep 11, 3:52 am, "b.a" <u4565...@anu.edu.au> wrote:
> Hi,
>
> Does anyone know how to place a legend (annotation) inside a draw
> widget? The legend that I use is somehow like this:
>
> mywindow = OBJ_NEW ( ' IDLgrWindow ' )
> myview = OBJ_NEW ( ' IDLgrView ' )
>
> itemNameArr = ['One', 'two']
>
> myLegend = OBJ_NEW ( ' IDLgrLegend ' , itemNameArr, /
> SHOW_OUTLINE)
>
> myview->Add, myLegend
> mywindow->Draw, myview
>
> and I have a Widget_draw that contains my plots (curves):
>
> dr_window = WIDGET_DRAW ( tlb , UVALUE= 'draw' )
>
> I know that by " mywindow->Draw, myview " the legend appears in
> separate window (like an image) but I couldn't find any way to place
> it inside my plot window (the widget_draw).
You need to add graphics_level=2 to the call to widget_draw, to make
it a window for object graphics. Then the draw widget's value will be
the window object where you should draw your view:
myview = OBJ_NEW ( ' IDLgrView ' )
itemNameArr = ['One', 'two']
myLegend = OBJ_NEW ( ' IDLgrLegend ' , itemNameArr, /SHOW_OUTLINE)
myview->Add, myLegend
dr_window = WIDGET_DRAW ( tlb , UVALUE= 'draw' , graphics_level=2)
widget_control,dr_window,get_value=mywindow
mywindow->Draw, myview
|
|
|
Re: Legend for plot [message #68114 is a reply to message #67975] |
Wed, 16 September 2009 19:57  |
penteado
Messages: 866 Registered: February 2018
|
Senior Member Administrator |
|
|
On Sep 16, 2:49 am, "b.a" <u4565...@anu.edu.au> wrote:
> What I mean, is to have the plot (and oplots) and the legend inside
> one window in my GUI. Actually my interface has several parts and one
> is a widget draw that will contain all the curves to be plotted. The
> problem is that when each curve is plotted, even though they have
> different colours, it is not clear which one is which. So I have to
> place a legend in there. I can't really use XYOUTS because I might
> have several plots which interrupt each other and I don't know where
> to place the XYOUTS :(
>
> Is it at all possible to place a legend inside a widget_draw which
> contains plots? The code that you wrote is what I want plus I need to
> put the plots in the same window.
>
> Thanks a lot.
Ok, now your initial question is more clear: how to put a legend into
your plot in the draw widget. You can go about it with object graphics
or direct graphics. I do not remember if there is a built in way to do
it in direct graphics (have not used them in years), but I know there
is a routine for that in IDLAstro (http://idlastro.gsfc.nasa.gov/),
though doing that way still required you to keep track of which lines/
symbols/colors were used on each plot, to use the same in the legend.
With object graphics, you can make and set yourself all the plot,
axes, symbols and legends, or use iplot to make the plots and put the
legends in them, then copy its view object to your draw widget. Taking
your example, it would be something like:
pro demolegend
x1 = [1,2,3,4,5]
y1 = [4,5,6,7,8]
x2 = [2,3,4,4.5,5]
y2 = [4,5,6,7,8]
tlb = Widget_Base(column=1, XSIZE=350, YSIZE= 400,$
XOFFSET=250, YOFFSET= 300)
dr_window = WIDGET_DRAW(tlb, UVALUE= 'draw', $
XSIZE= 348, YSIZE=200, GRAPHICS_LEVEL = 2)
Widget_Control, tlb, /realize
WIDGET_CONTROL, dr_window, GET_VALUE = mywindow
;make the plots in an invisible itool
iplot,y2,x2,color=[255,0,0],name='one ',insert_legend=[0.,0.],$
dimensions=[348,200],$
/no_saveprompt,/disable_splash,user_interface='none'
iplot,y1,x1,color=[0,0,255],name='two ',/insert_legend,/over
;get the itool object
id=itgetcurrent(tool=ot)
;unselect the currently selected object, if any
osel=ot->getselecteditems(count=nosel,/all)
for i=0,nosel-1 do osel[i]->select,/unselect
;get the view object from the itool (assuming all ploting has been
done)
myview=ot->getbyidentifier(ot->findidentifiers('*/WINDOW/VIEW_1'))
mywindow->Draw, myview
;close the itool
itdelete,id
Xmanager, 'demolegend', tlb
end
Note that the legend is not being created by this program, it is made
by iplot.
|
|
|