[vtkusers] Drawing a simple line graph

John Platt jcplatt at dsl.pipex.com
Sat Nov 18 18:24:31 EST 2006


Hi,

I would use vtkXYPlotActor as a template for your other types of plot.
Use viewport coordinates for your axes and your points (the default for
vtkPolyDataMapper2D). Create the point values after the plot area and
axes have been positioned. Normalise your plot data then scale it by the
length of each axis (pos2-pos) which will be pixels for viewport
coordinates.

Try modifying vtkXYPlotActor::CreatePlotData() for your custom plots.

Anyway, here is your original code with some changes.

   // Some points to plot.
   vtkPoints* polyLinePoints = vtkPoints::New();
   polyLinePoints->InsertNextPoint( 0, 0, 0 );
   polyLinePoints->InsertNextPoint(  50, 20, 0 );
   polyLinePoints->InsertNextPoint( 100, 60, 0 );
   polyLinePoints->InsertNextPoint( 160, 50, 0 );
   polyLinePoints->InsertNextPoint( 200, 100, 0 );

   double* bounds = polyLinePoints->GetBounds();
   double xRange[2]; xRange[0]=bounds[0]; xRange[1]=bounds[1]; 
   double yRange[2]; yRange[0]=bounds[2]; yRange[1]=bounds[3]; 

   // All the lines joining the plot points.
   vtkCellArray* lines = vtkCellArray::New();
   for ( int i = 0; i < polyLinePoints->GetNumberOfPoints() - 1; ++i )
   {
      vtkIdType topol[2];
      topol[0] = i;
      topol[1] = i+1;
      lines->InsertNextCell( 2, topol );
   }

   // Create polydata from points & lines.
   vtkPolyData* polydata = vtkPolyData::New();
   polydata->SetPoints(polyLinePoints);
   polydata->SetLines(lines);
   polydata->BuildCells();

   // Map it to 2D.
   vtkPolyDataMapper2D* mapper = vtkPolyDataMapper2D::New();
   mapper->SetInput(polydata);
   vtkActor2D* actor = vtkActor2D::New();
   actor->SetMapper(mapper);

   // The default coordinate systems for positioning 2D actors are
VIEWPORT
   // coordinates for SetPosition() and NORMALISED VIEWPORT relative to
Position
   // for SetPosition2(). Change SetPosition() to use NORMALISED
VIEWPORT.

 
actor->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport(
);
   actor->GetPositionCoordinate()->SetValue(0.2, 0.2);
   actor->GetPosition2Coordinate()->SetValue(0.6, 0.7);
   actor->GetProperty()->SetColor(1, 0, 0);

   // Define axes
   vtkAxisActor2D *axesX = vtkAxisActor2D::New();
   axesX->GetPositionCoordinate()->SetCoordinateSystemToViewport();
   axesX->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
   axesX->SetLabelFormat("%g");
   axesX->SetRange( xRange );
   axesX->SetTitle("Time (s)");

   vtkAxisActor2D *axesY = vtkAxisActor2D::New();
   axesY->GetPositionCoordinate()->SetCoordinateSystemToViewport();
   axesY->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
   axesY->SetLabelFormat("%g");
   axesY->SetRange( yRange[1], yRange[0] ); // note reversal

   // Add plot actor and axes actors to renderer.
   vtkRenderer* ren = vtkRenderer::New(); 
   ren->AddActor2D(actor);
   ren->AddViewProp(axesX);
   ren->AddViewProp(axesY);

   vtkRenderWindow* renWin = vtkRenderWindow::New();    
   renWin->AddRenderer(ren);
   renWin->SetSize( 801, 601 );

   vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
   iren->SetRenderWindow(renWin);
   iren->Initialize(); // need a window size to determine viewport
coordinates

   // Position axes using the plot actor viewport coordinates.
   int* p  =
actor->GetPositionCoordinate()->GetComputedViewportValue(ren);
   double pos[2]; pos[0]=(double)p[0]; pos[1]=(double)p[1];
   int* p2 =
actor->GetPosition2Coordinate()->GetComputedViewportValue(ren);
   double pos2[2]; pos2[0]=(double)p2[0]; pos2[1]=(double)p2[1]; 

   axesX->GetPositionCoordinate()->SetValue( pos  );
   axesX->GetPosition2Coordinate()->SetValue( pos2[0], pos[1]  );
   axesY->GetPositionCoordinate()->SetValue(  pos[0],  pos2[1] ); //
left, top
   axesY->GetPosition2Coordinate()->SetValue( pos  );             //
left, bottom

   // Convert plot data to VIEWPORT coordinates (pixel centres relative
to the
   // Position() coordinate of the plot actor).

   for ( i = 0; i < polyLinePoints->GetNumberOfPoints(); ++i )
   {
      double* xyz = polyLinePoints->GetPoint( i );
      xyz[0] =
(xyz[0]-xRange[0])/(xRange[1]-xRange[0])*(pos2[0]-pos[0]);
      xyz[1] =
(xyz[1]-yRange[0])/(yRange[1]-yRange[0])*(pos2[1]-pos[1]);
      xyz[2] = 0.0;
      polyLinePoints->SetPoint( i, xyz  );
   }

   renWin->Render();
   iren->Start();

   return 0;

HTH

John.

-----Original Message-----
From: beth at portugalmail.pt [mailto:beth at portugalmail.pt] 
Sent: 17 November 2006 19:30
To: John Platt
Cc: vtkusers at vtk.org
Subject: RE: [vtkusers] Drawing a simple line graph 

Hi,

I used non-normalized values, such as time (in seconds) and heartbeat 
frequency (between 70 up to 160). These values are captured by sensors,
and 
are  integers (70-160) and floats (0.000-78.675). They define x (time)
and y 
(heartbeat) values.

I thought that they would be properly converted by the mapper...

By the way, I used vtkXYPlotActor and it worked perfectly. However, I
would 
still want to know what is wrong here, because I want to create other
types of 
graphs (bar, histograms, area, etc.).

Thanks and best regards,

Elizabeth

Citando John Platt <jcplatt at dsl.pipex.com>:

 Hi,
 
 By default, vtkPolyDataMapper2D, transforms 3D data into 2D data by
 ignoring the z-coordinate of the 3D points in vtkPolyData, and taking
 the (x,y) values as VIEWPORT values (pixel centers relative to the
 lower-left corner of the viewport in the render window).
 
 What values have you used in 'polyLinePoints'.
 
 John.
 
 -----Original Message-----
 From: vtkusers-bounces+jcplatt=dsl.pipex.com at vtk.org
 [mailto:vtkusers-bounces+jcplatt=dsl.pipex.com at vtk.org] On Behalf Of
 beth at portugalmail.pt
 Sent: 17 November 2006 13:33
 To: John Platt
 Cc: vtkusers at vtk.org
 Subject: RE: [vtkusers] Drawing a simple line graph 
 
 Hi,
 
 Yes, I know that Position2 is relative to Position. But evend adjusting
 other 
 values, it does not work.
 No, I can try to use vtkXYPlotActor, however I do want also to create
an
 area 
 graph (using a polygon instead a polyline), and for that, I'll have to
 know 
 how to work properly with this situation...
 
 Any other tip?
 
 Thanks and best regards,
 
 Elizabeth
 
 
 Citando John Platt <jcplatt at dsl.pipex.com>:
 
  Hi,
  
  I seem to recall that the Position2 coordinate is relative to
Position.
  
  Is there any reason you cannot use vtkXYPlotActor?
  
  John.
  
  -----Original Message-----
  From: vtkusers-bounces+jcplatt=dsl.pipex.com at vtk.org
  [mailto:vtkusers-bounces+jcplatt=dsl.pipex.com at vtk.org] On Behalf Of
  beth at portugalmail.pt
  Sent: 16 November 2006 20:53
  To: vtkusers at vtk.org
  Subject: [vtkusers] Drawing a simple line graph 
  
  Hi,
   
  I'm trying to create a simple line graph. For that, I created a
 polyline
  and 2 
  axis.My piece of code looks like this:
   
  // Create a polyline
   vtkPolyData* polydata = vtkPolyData::New();
   polydata->SetPoints(polyLinePoints);
   polydata->SetLines(line);
   
  // Maps it to 2D
   vtkPolyDataMapper2D *mapper = vtkPolyDataMapper2D::New();
   mapper->SetInput(polydata);
   
  // Creates an actor, defining its limits according the graph area
  defined by 
  the axes below
   vtkActor2D *actor = vtkActor2D::New();
   actor->SetMapper(mapper);
   
  
 
actor->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport(
  );
   actor->GetPositionCoordinate()->SetValue(0.05, 0.2);
   
  
 
actor->GetPosition2Coordinate()->SetCoordinateSystemToNormalizedViewport
  (); // it's not working properly!!!
   actor->GetPosition2Coordinate()->SetValue(0.90, 0.9); // it's not
  working 
  properly!!!
   actor->GetProperty()->SetColor(1, 0, 0);
  
  // Define axes
   vtkCoordinate *coords_x1 = vtkCoordinate::New();
   coords_x1->SetValue(0.05, 0.2);
   
   vtkCoordinate *coords_x2 = vtkCoordinate::New();
   coords_x2->SetValue(0.95, 0.2);
   
   vtkCoordinate *coords_y1 = vtkCoordinate::New();
   coords_y1->SetValue(0.05, 0.2);
   
   vtkCoordinate *coords_y2 = vtkCoordinate::New();
   coords_y2->SetValue(0.05, 0.95);
   
   vtkAxisActor2D *axesX = vtkAxisActor2D::New();
   axesX->SetPoint1(coords_x1->GetValue());
   axesX->SetPoint2(coords_x2->GetValue());
   axesX->SetLabelFormat("%3.2f");
   axesX->SetFontFactor(1.2);
   axesX->SetRange(0, t); // t is the maximum x value in the polyline
  points
   axesX->SetTitle("Time (s)");
   axesX->SetNumberOfLabels(10);
   axesX->AdjustLabelsOn();
   axesX->LabelVisibilityOn();
   axesX->TickVisibilityOn();
   
   vtkAxisActor2D *axesY = vtkAxisActor2D::New();
   axesY->SetPoint1(coords_y1->GetValue());
   axesY->SetPoint2(coords_y2->GetValue());
   axesY->SetLabelFormat("%3.2f");
   axesY->SetFontFactor(1);
   axesY->SetRange(0, sCardMax); // Máximum y value in polyline points
   axesY->AdjustLabelsOn();
   axesY->LabelVisibilityOn();
   axesY->TickVisibilityOn();
   
  .....the usual stuff....creates the renderer...
   
  rw->AddActor2D(actor);
  rw->AddViewProp(axesX);
  rw->AddViewProp(axesY);
   
   
  Well, the line graph is drawn, but the problem is that axes values and
  line 
  values are not matching. 
  It seems that the GetPosition2Coordinate is not working at all,
because
  the 
  mapping of the line to the graph effective area (that is defined by
the
  limits 
  of the axes - xmin, ymin and xmax, ymax) is not being done. It just
 puts
  the 
  polyline at the initial position defined by GetPositionCoordinate, and
  draws 
  it as the output given by the vtkPolyDataMapper2D.
   
  What should I do?
   
  Thanks for any help!
   
  Regards,
   
  Elizabeth
  
  __________________________________________________________
  O email preferido dos portugueses agora com
  2 000 MB de espaço e acesso gratuito à Internet
  http://www.portugalmail.pt/2000mb
  _______________________________________________
  This is the private VTK discussion list. 
  Please keep messages on-topic. Check the FAQ at:
  http://www.vtk.org/Wiki/VTK_FAQ
  Follow this link to subscribe/unsubscribe:
  http://www.vtk.org/mailman/listinfo/vtkusers
  
  
  
 
 
 
 __________________________________________________________
 O email preferido dos portugueses agora com
 2 000 MB de espaço e acesso gratuito à Internet
 http://www.portugalmail.pt/2000mb
 _______________________________________________
 This is the private VTK discussion list. 
 Please keep messages on-topic. Check the FAQ at:
 http://www.vtk.org/Wiki/VTK_FAQ
 Follow this link to subscribe/unsubscribe:
 http://www.vtk.org/mailman/listinfo/vtkusers
 
 
 



__________________________________________________________
O email preferido dos portugueses agora com
2 000 MB de espaço e acesso gratuito à Internet
http://www.portugalmail.pt/2000mb





More information about the vtkusers mailing list