[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