[vtkusers] Positioning titles within vtkAxis

Marcus D. Hanwell marcus.hanwell at kitware.com
Tue Dec 7 15:30:55 EST 2010


Hi,

I will take a look at this, but the vtkAxis has not been used much outside
of charts. Calling Update should help, after making all changes. There is a
new 2D histogram class I am actively developing that does most of what you
have done there. You seem to construct actors that are not required in the
code. I will see if I can take a better look at this later when I have more
time, I am actively fixing bugs right now in preparation for the VTK and
ParaView branches.

It is great to see more people experimenting with these classes, I will get
an updated guide to the 2D world in VTK once I have a little time. I think
the axis updates need a little refactoring as I have found it to be a little
too fragile - so this is something I am looking at.

Marcus

On Tue, Dec 7, 2010 at 1:05 PM, Eric E. Monson <emonson at cs.duke.edu> wrote:

> Hey Daniel,
>
> There seems to be something wrong with the painting for vtkAxis when used
> by itself in a scene. I'm not sure why we don't see this behavior when these
> axes are used within the charts. Hopefully Marcus will be able to take a
> look. You can see the problem even in the attached simple Python script.
>
> One thing I noticed that maybe Marcus can comment on: Things like
> vtkChartXY do an Update on themselves before Paint. If in this script you
> don't call Update explicitly on the axis objects they paint the axis line
> and title, but not the ticks and their labels. Maybe it would be good to add
> and Update call at the beginning of vtkAxis::Paint?
>
> Daniel, something you might want to consider instead of the method you're
> using now is a trick others are using for vtkScalarsToColorsItem and its
> subclasses: they make a subclass of vtkPlot which has a vtkImageData as a
> private Texture variable, and then paints the texture within the plot's
> bounds. This way they can instantiate a vtkChartXY and use AddPlot() to add
> what is basically an image painter, and then vtkChartXY takes care of the
> axes internally. Just an idea that I've seen the developers using.
>
> Anyway, hopefully Marcus or someone else will be able to take a look at
> this sometime soon, but I know he's very busy right now.
>
> Talk to you later,
> -Eric
>
> # =======
> import vtk
>
> view = vtk.vtkContextView()
> view.GetRenderWindow().SetSize(400, 300)
>
> axis1 = vtk.vtkAxis()
> axis1.SetPoint1(75,75)
> axis1.SetPoint2(75,225)
> axis1.SetPosition(vtk.vtkAxis.LEFT)
> axis1.SetTitle('YAxis')
> axis1.Update()
> view.GetScene().AddItem(axis1)
>
> axis2 = vtk.vtkAxis()
> axis2.SetPoint1(75,75)
> axis2.SetPoint2(325,75)
> axis2.SetPosition(vtk.vtkAxis.BOTTOM)
> axis2.SetTitle('XAxis')
> axis2.Update()
> view.GetScene().AddItem(axis2)
>
> view.Render()
> view.GetInteractor().Start()
> # =======
>
> On Dec 7, 2010, at 10:46 AM, Frese Daniel Dr. wrote:
>
> Hi Eric,
>
> here it is, or at least the relevant part.
> I’m sorry it’s a bit lengthy, even though I omitted some stuff around. I
> did this
> in the Visual Studio and created a WinForms control (which by the way
> worked nicely),
> so “this” points to an instance of the form in order to get the dimensions
> of the output window.
> The double locdata array and the dimensions of the image etc. are stored in
> private elements of the
> WinForm control.
>
> This is basically my first effort with these routines in order to try out
> things,
> so I wouldn’t be surprised if things can be done in a better way. I put the
> axes
> in a different scene in order to work around some strange things when using
> vtk 5.6.1,
> but now I am using the latest git stuff (or nearly, I downloaded yesterday
> afternoon)
> and there is no need any more for any workarounds (vtk & life has become
> better J).
> Placing the axes into the view’s scene does not change their behavior
> however (I tested).
>
> Thank you very much for your interest in this !
> Daniel
>
>
>       void vtk2dDataControl::VTKRender() {
>             double *minmax;                          // min and max within
> the data
>             int nColors = 1000;                      // number of colors
>             double colorposition[2];           // holds the position of
> the colorbar
>             int windowsizeX;                   // X window size - to be
> supplied externally
>             int windowsizeY;                   // Y window size - to be
> supplied externally
>             int imageextent[6];                      // extent of the
> imgage
>             int barwidth = 120;                      // FIXME, X space for
> colorbar
>             int labelnum;                            // number of labels -
> a helper var
>             int upperborder = 20;              // border space between
> upper image edge and window edge
>             int rightborder = 40;              // space between image and
> colorbar
>             int i;
>
>
>             // calculate the effective width of the window, that can be
> used for the display
>             windowsizeX = this->Width;
>             windowsizeY = this->Height;
>             effectiveSizeX = windowsizeX  - imageposition[0] - barwidth -
> rightborder;
>             effectiveSizeY = windowsizeY  - imageposition[1] - upperborder;
>
>             // import the data into the vtkimagedata structure
>             VTK_CREATE(vtkImageImport, import);
>             import->SetImportVoidPointer(localdata);
>             import->SetDataScalarTypeToDouble();
>             import->SetWholeExtent(0,locdimX-1,0,locdimY-1,0,0);
>             import->SetDataExtent(0,locdimX-1,0,locdimY-1,0,0);
>             import->Update(); // call update for getting the right minmax
> values below...
>             minmax = import->GetOutput()->GetScalarRange();
>
>             // resample the image in order to fit into the given window
> geometry
>             VTK_CREATE(vtkImageResample, resample);
>             resample->SetInputConnection(import->GetOutputPort());
>             resample->SetDimensionality(2);
>             resample->SetAxisMagnificationFactor(0, ((double)
> effectiveSizeX) / locdimX);
>             resample->SetAxisMagnificationFactor(1, ((double)
> effectiveSizeY) / locdimY);
>
>             // add a colorbar
>             VTK_CREATE(vtkLookupTable, lookupTable);
>             VTK_CREATE(vtkScalarBarActor, colorbar);
>             lookupTable->SetNumberOfColors(nColors);
>             lookupTable->SetTableRange(minmax);
>             //lookupTable->SetSaturationRange(0, 1);
>             //lookupTable->SetHueRange(0, 1);
>             lookupTable->SetRampToLinear();
>             lookupTable->Build();
>
>             // Filter to convert the grey image into an RGB output
>             VTK_CREATE(vtkImageMapToColors, rgb);
>             rgb->SetInputConnection(resample->GetOutputPort());
>             rgb->SetLookupTable(lookupTable);
>             rgb->SetOutputFormatToRGBA();
>             rgb->Update();
>
>             // Set up a 2D context view - this is the basic 2D API
> structure
>             if (view != NULL) view->Delete();
>             view = vtkContextView::New();
>             view->GetRenderWindow()->SetSize(windowsizeX, windowsizeY);
>
>             // register the image into the view and position it
>             VTK_CREATE(vtkImageItem, item);
>             view->GetScene()->AddItem(item);
>             item->SetImage(vtkImageData::SafeDownCast(rgb->GetOutput()));
>             item->GetImage()->GetExtent(imageextent);
>             item->SetPosition(imageposition[0], imageposition[1]);
>
>             // create a new scene for axes and colorbar; also create actor
> for axes
>             VTK_CREATE(vtkContextScene, axesscene);
>             VTK_CREATE(vtkContextActor, axesactor);
>
>             // Starting from here there is mainly stuff for the axes...
>             // X Axis
>             VTK_CREATE(vtkAxis, Xaxis);
>             Xaxis->SetBehavior(1); // rescalable
>             // now define location of axis by giving two points
>             Xaxis->SetPoint1(imageposition[0], imageposition[1]);
>             Xaxis->SetPoint2((int) imageextent[1]-imageextent[0] +
> imageposition[0], imageposition[1]);
>             Xaxis->SetPosition(vtkAxis::BOTTOM);     // this is an axis at
> the bottom
>             Xaxis->SetTitle(XAxisName->c_str());     // title of axis
>             Xaxis->GetPen()->SetWidth(2);            // lines are 2 pixel
> wide
>             Xaxis->SetMinimum(locXmin);                    // set Xmin and
> ...
>             Xaxis->SetMaximum(locXmax);                    // ... Xmax for
> later autoscale()
>             Xaxis->SetPrecision(2);                        // two figures
> after period
>             Xaxis->SetNotation(2);                         // "mixed"
> (i.e. standard or scientific)
>             Xaxis->AutoScale();                                  //
> perform autoscale for ticks
>             Xaxis->Update();                               // do it !
>             Xaxis->SetMinimum(locXmin);                    // got to reste
> min/max values afetr autoscale
>             Xaxis->SetMaximum(locXmax);
>             Xaxis->GetGridPen()->SetColor(0,0,0,1); // write in black
>             Xaxis->SetLabelsVisible(true);                 // show it
> all...
>             Xaxis->SetVisible(true);
>             //Xaxis->GetTitleProperties()->SetLineOffset(10);
>             Xaxis->Update();                               // do it !
>             axesscene->AddItem(Xaxis);                     // add to scene
>
>             // Y Axis
>             // everything completely analogous to X Axis - so no need for
> comments here
>             VTK_CREATE(vtkAxis, Yaxis);
>             Yaxis->SetBehavior(1);
>             Yaxis->SetPoint1(imageposition[0], imageposition[1]);
>             Yaxis->SetPoint2(imageposition[0], (int)
> imageextent[3]-imageextent[2] + imageposition[1]);
>             Yaxis->SetPosition(vtkAxis::LEFT);
>             Yaxis->SetTitle(YAxisName->c_str());
>             Yaxis->GetPen()->SetWidth(2);
>             Yaxis->SetMinimum(locYmin);
>             Yaxis->SetMaximum(locYmax);
>             Yaxis->AutoScale();
>             Yaxis->Update();
>             Yaxis->SetMinimum(locYmin);
>             Yaxis->SetMaximum(locYmax);
>             Yaxis->GetGridPen()->SetColor(0,0,0,1);
>             Yaxis->GetTitleProperties()->SetOrientation(90.0);
>             Yaxis->SetLabelsVisible(true);
>             Yaxis->SetVisible(true);
>             Yaxis->Update();
>             axesscene->AddItem(Yaxis);
>
>             // prepare axes on top and on right w/o labels (just ticks)
>             labelnum = Xaxis->GetTickPositions()->GetDataSize();
>             VTK_CREATE(vtkStringArray, Xemptylabels);
>             Xemptylabels->SetNumberOfValues(labelnum);
>             for (i=0; i<labelnum; i++) {
>                   Xemptylabels->SetValue(i, "");
>             }
>             labelnum = Yaxis->GetTickPositions()->GetDataSize();
>             VTK_CREATE(vtkStringArray, Yemptylabels);
>             Yemptylabels->SetNumberOfValues(labelnum);
>             for (i=0; i<labelnum; i++) {
>                   Yemptylabels->SetValue(i, "");
>             }
>
>             // create axis on top of image
>             VTK_CREATE(vtkAxis, XaxisUpper);
>             XaxisUpper->SetBehavior(1);
>             XaxisUpper->SetPoint1(imageposition[0], imageposition[1] + (
> int) (imageextent[3]-imageextent[2]));
>             XaxisUpper->SetPoint2((int) imageextent[1]-imageextent[0] +
> imageposition[0], imageposition[1] + (int)
> (imageextent[3]-imageextent[2]));
>             XaxisUpper->SetPosition(vtkAxis::TOP);
>             XaxisUpper->GetPen()->SetWidth(2);
>             XaxisUpper->SetMinimum(locXmin);
>             XaxisUpper->SetMaximum(locXmax);
>             // want to have same number of ticks as X axis ...
>
> XaxisUpper->SetNumberOfTicks(Xaxis->GetTickPositions()->GetDataSize());
>             XaxisUpper->GetGridPen()->SetColor(0,0,0,1);
>             // ... and same positions of ticks as X axis ...
>             XaxisUpper->SetTickPositions(Xaxis->GetTickPositions());
>             // .. but no labels this time.
>             XaxisUpper->SetTickLabels(Xemptylabels);
>             XaxisUpper->SetVisible(true);
>             XaxisUpper->Update();
>             axesscene->AddItem(XaxisUpper);
>
>             // create axis on the right of top image - analogous to
> XaxisUpper above
>             VTK_CREATE(vtkAxis, YaxisRight);
>             YaxisRight->SetBehavior(1);
>             YaxisRight->SetPoint1(imageposition[0] + (int)
> imageextent[1]-imageextent[0], imageposition[1]);
>             YaxisRight->SetPoint2(imageposition[0] + (int)
> imageextent[1]-imageextent[0], (int) imageextent[3]-imageextent[2] +
> imageposition[1]);
>             YaxisRight->SetPosition(vtkAxis::RIGHT);
>             YaxisRight->GetPen()->SetWidth(2);
>             YaxisRight->SetMinimum(locYmin);
>             YaxisRight->SetMaximum(locYmax);
>
> YaxisRight->SetNumberOfTicks(Yaxis->GetTickPositions()->GetDataSize());
>             YaxisRight->GetGridPen()->SetColor(0,0,0,1);
>             YaxisRight->SetTickPositions(Yaxis->GetTickPositions());
>             YaxisRight->SetTickLabels(Yemptylabels);
>             YaxisRight->SetVisible(true);
>             YaxisRight->Update();
>             axesscene->AddItem(YaxisRight);
>
>             // now format and position colorbar
>             colorbar->SetLookupTable(lookupTable);
>             colorposition[0] = 1.0 - (1.0* barwidth)/windowsizeX;
>             colorposition[1] = (1.0* imageposition[1])/windowsizeY;
>             colorbar->SetWidth(0.5);
>             colorbar->SetHeight(1.0 - 2* colorposition[1]);
>             colorbar->SetPosition(colorposition);
>             colorbar->SetLabelFormat("%1.2E");
>             colorbar->PickableOff();
>             colorbar->SetMaximumWidthInPixels(barwidth);
>             colorbar->VisibilityOn();
>             colorbar->GetLabelTextProperty()->SetShadow(0);
>             colorbar->GetLabelTextProperty()->SetColor(0,0,0);
>
>             // register the axescene to the axesactor, which and point to
> the renderer
>             axesactor->SetScene(axesscene);
>             view->GetRenderer()->AddActor(axesactor);
>
>             // register the colorbar as an actor
>             view->GetRenderer()->AddActor(colorbar);
>
>             RenderWindow = view->GetRenderWindow();
>             RenderWindow->SetWindowId((HWND)Handle.ToInt64());
>
>             // set Interactor Style to RubberBand
>             VTK_CREATE(vtkInteractorStyleRubberBand2D, RubberBandStyle);
>             RubberBandStyle->SetRenderOnMouseMove(false);
>             VTK_CREATE(vtkCallbackCommand, SelectionChangedCallback);
>
> SelectionChangedCallback->SetCallback(SelectionChangedCallbackFunction);
>
> RubberBandStyle->AddObserver(vtkCommand::SelectionChangedEvent,SelectionChangedCallback);
>             RenderWindow->SetInteractor(WinInteractor);
>             RenderWindow->SetDoubleBuffer(1);
>             WinInteractor->SetInteractorStyle(RubberBandStyle);
>             WinInteractor->Initialize();
>       }
>
> *Von:* Eric E. Monson [mailto:emonson at cs.duke.edu]
> *Gesendet:* Dienstag, 7. Dezember 2010 16:13
> *An:* Frese Daniel Dr.
> *Cc:* Marcus D. Hanwell; vtkusers at vtk.org
> *Betreff:* Re: AW: [vtkusers] Positioning titles within vtkAxis
>
> Hey Daniel,
>
> Yes, this shouldn't be happening. Would you be able to send the section of
> your code that generates this chart? I'm curious how you're implementing the
> combination of ImageItem and axes. Maybe there is another way of
> accomplishing the same thing that wouldn't cause the overlap, or it might at
> least help us diagnose why the label placement routine isn't dealing with
> your case correctly.
>
> Also, just to be clear, was this generated with the current development
> (git) version, or with 5.6.1?
>
> Thanks,
> -Eric
>
>
> On Dec 7, 2010, at 8:29 AM, Frese Daniel Dr. wrote:
>
>
> Hello Eric, Marcus,
>
> before I explain my problem once more I just want to add that I find the
> charts functionality already quite useful.
> As I said I just updated my vtk stuff and I can imagine it must have been
> quite some work to get to this point.
>
> I appended a screenshot illustrating the problem. Since I don’t know how
> this appears on the mail list I just describe briefly.
> I have a scene with a vtkImageItem to show some 2D matrix data. Around the
> image I have axes (vtkAxis objects) with
> appropriate ticks, tick labels and axes titles. The problem is that the
> axes titles overlap with the tick labels. E.g. for the
> case of the X axis , the title should be lower such that it does not touch
> the labels, but there does not seem to
> be a way to do that as of now.
>
> A possible low level solution would be a way to specify some vertical
> (horizontal axis case) or some horizontal (vertical axis case) offset
> for the position of the titles (in pixel or font size units).
> In principle of course the vtkAxis object could calculate such an offset by
> itself, since it has access to both
> the labels’ and the titles’ text properties.
>
> What do you think ?
> Daniel
>
> *Von:* Eric E. Monson [mailto:emonson at cs.duke.edu]
> *Gesendet:* Dienstag, 7. Dezember 2010 13:54
> *An:* Frese Daniel Dr.
> *Cc:* vtkusers at vtk.org
> *Betreff:* Re: [vtkusers] Positioning titles within vtkAxis
>
> Hey Daniel,
>
> It does seem like SetLineOffset should do something like what you want, but
> I think they way the label text is applied with VerticalJustification
> probably nullifies any line offset setting. Line spacing shouldn't matter
> for a single line of text.
>
> So, the adjustments you want are just not implemented. Marcus, the
> developer, has worked hard to get the labels right, though, so if you have a
> use case where the labels are running into the axis ticks maybe you should
> describe the situation and send a screen shot – it may be something that
> needs fixing.
>
> You're right that the charts are still under development, but some of the
> core functionality has settled down, and as you said, the current
> implementation is better than the 5.6.1 version.
>
> -Eric
>
> ------------------------------------------------------
> Eric E Monson
> Duke Visualization Technology Group
>
>
>
>
> On Dec 7, 2010, at 3:35 AM, Frese Daniel Dr. wrote:
>
>
>
> Hi all,
>
> I have a problem positioning an axis title relative to its vtkAxis object.
> Basically, if I draw a horizontal  X-axis, the assigned title is written
> such that it overlapps with the
> tick labels. Reading through the docs, I got the impression that I should
> be able to introduce a
> vertical offset between the drawn axis and the titel by using either a call
> to
> Xaxis->GetTitleProperties()->SetLineOffset(offset_in_pixel)
> or by
> Xaxis->GetTitleProperties()->SetLineSpacing(scale_factor).
> But neither call seems to have any effect.
> Moving from 5.6.1 to the latest vtk git source tree I noticed that the
> chart stuff seems to have
> improved greatly (most functions a joy to use !), but it still seems to be
> a work in progress.
> So am doing something stupid and do I miss something here or is this
> feature just not
> implemented yet ?
>
> Daniel
>
> </PRE><p>
> ------------------------------------------------------------------------------------------------------
> <br>
> Registergericht: Traunstein / Registry Court: HRB 275 - Sitz / Head Office:
> Traunreut <br>
> Aufsichtsratsvorsitzender / Chairman of Supervisory Board: Rainer Burkhard
> <br>
> Geschäftsführung / Management Board: Thomas Sesselmann (Vorsitzender /
> Chairman),<br>
> Michael Grimm, Matthias Fauser, Sebastian Tondorf<br><br>
> <a href="http://www.heidenhain.de/disclaimer" target="_blank">E-Mail
> Haftungsausschluss / E-Mail Disclaimer</a><br><pre>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20101207/e7b5ad55/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/png
Size: 16550 bytes
Desc: not available
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20101207/e7b5ad55/attachment.png>


More information about the vtkusers mailing list