[vtkusers] plotting bar chart with vtkBarChartActor and vtkXYPlotActor
michiel mentink
michael.mentink at st-hughs.ox.ac.uk
Sat Jan 9 05:01:56 EST 2010
Dear David,
Actually, I took Dean's examples and added a bit of code that saves the
frequencies
and their components to a text file. The text file can be opened in a
spreadsheet program,
so you can produce the same plot.
It's not a very significant change, might be useful for people that are
writing about
their data set?
Michael
On Sat, Jan 9, 2010 at 12:08 AM, David Doria
<daviddoria+vtk at gmail.com<daviddoria%2Bvtk at gmail.com>
> wrote:
> On Thu, Jan 7, 2010 at 9:31 AM, michiel mentink
> <michael.mentink at st-hughs.ox.ac.uk> wrote:
> > oops. Forgot a small error. Correct now.
> >
> >
> >
> >
> > #include <vtkActor.h>
> > #include <vtkImageAccumulate.h>
> > #include <vtkImageData.h>
> > #include <vtkImageExtractComponents.h>
> > #include <vtkJPEGReader.h>
> > #include <vtkRenderer.h>
> > #include <vtkRenderWindow.h>
> > #include <vtkRenderWindowInteractor.h>
> > #include <vtkSmartPointer.h>
> > #include <vtkStdString.h>
> > #include <vtkXYPlotActor.h>
> > #include <vtkPointData.h>
> >
> > int main( int argc, char *argv[] )
> > {
> > // Handle the arguments
> > if( argc < 2 )
> > {
> > vtkstd::cout << "Required arguments: filename.jpg, [optional ignore
> > zero:] <y/n>" << vtkstd::endl;
> > return EXIT_FAILURE;
> > }
> >
> > int ignoreZero = 0;
> > if( argc == 3 )
> > {
> > vtkStdString ignore = argv[2];
> > cout << ignore << endl;
> > if( ignore == "y" || ignore == "Y" )
> > {
> > ignoreZero = 1;
> > }
> > }
> >
> > // Read a jpeg image
> > //
> > vtkSmartPointer<vtkJPEGReader> reader =
> > vtkSmartPointer<vtkJPEGReader>::New();
> > if( !reader->CanReadFile( argv[1] ) )
> > {
> > vtkstd::cout << "Error: cannot read " << argv[1] << vtkstd::endl;
> > return EXIT_FAILURE;
> > }
> > reader->SetFileName( argv[1] );
> > reader->Update();
> >
> > int numComponents = reader->GetOutput()->GetNumberOfScalarComponents();
> > if( numComponents > 3 )
> > {
> > vtkstd::cout << "Error: cannot process an image with " <<
> numComponents
> > << " components!" << vtkstd::endl;
> > return EXIT_FAILURE;
> > }
> >
> > // Create a vtkXYPlotActor
> > //
> > vtkSmartPointer<vtkXYPlotActor> plot =
> > vtkSmartPointer<vtkXYPlotActor>::New();
> > plot->ExchangeAxesOff();
> > plot->SetLabelFormat( "%g" );
> > plot->SetXTitle( "Level" );
> > plot->SetYTitle( "Frequency" );
> > plot->SetXValuesToValue();
> >
> > double xmax = 0.;
> > double ymax = 0.;
> >
> > double colors[3][3] = {
> > { 1, 0, 0 },
> > { 0, 1, 0 },
> > { 0, 0, 1 } };
> >
> > const char* labels[3] = {
> > "Red", "Green", "Blue" };
> >
> > // Process the image, extracting and plotting a histogram for each
> > component
> > //
> > //
> >
> > ofstream myfile;
> > myfile.open ("histogram.txt");
> > myfile << "Pixel intensities and their counts.\n";
> >
> > for( int i = 0; i < numComponents; ++i )
> > {
> > vtkSmartPointer<vtkImageExtractComponents> extract =
> > vtkSmartPointer<vtkImageExtractComponents>::New();
> > extract->SetInputConnection( reader->GetOutputPort() );
> > extract->SetComponents( i );
> > extract->Update();
> >
> > double range[2];
> > extract->GetOutput()->GetScalarRange( range );
> > vtkSmartPointer<vtkImageAccumulate> histogram =
> > vtkSmartPointer<vtkImageAccumulate>::New();
> > histogram->SetInputConnection( extract->GetOutputPort() );
> > histogram->SetComponentExtent(
> > 0,static_cast<int>(range[1])-static_cast<int>(range[0])-1,0,0,0,0 );
> > histogram->SetComponentOrigin( range[0],0,0 );
> > histogram->SetComponentSpacing( 1,0,0 );
> > histogram->SetIgnoreZero( ignoreZero );
> > histogram->Update();
> >
> > if( range[1] > xmax ) xmax = range[1];
> > if( histogram->GetOutput()->GetScalarRange()[1] > ymax ) ymax =
> > histogram->GetOutput()->GetScalarRange()[1];
> >
> > plot->AddInput( histogram->GetOutput() );
> >
> > if( numComponents > 1 )
> > {
> > plot->SetPlotColor(i,colors[i]);
> > plot->SetPlotLabel(i,labels[i]);
> > plot->LegendOn();
> >
> > myfile << "\n" << labels[i] << "\n\n";
> > }
> >
> > unsigned int temp = (range[1]-1);
> > unsigned int frequency[temp];
> >
> > std::cout<< "range: " << range[0] << " " << range[1] <<std::endl;
> >
> > unsigned int j;
> >
> > for(j=0;j<temp;j++){
> > frequency[j]=0;
> > frequency[j] =
> > histogram->GetOutput()->GetPointData()->GetScalars()->GetTuple1(j);
> > myfile << j << "\t" << frequency[j] << "\n";
> > }
> > }
> >
> > myfile.close();
> >
> > plot->SetXRange( 0, xmax );
> > plot->SetYRange( 0, ymax );
> >
> > // Visualize the histogram(s)
> > vtkSmartPointer<vtkRenderer> renderer =
> > vtkSmartPointer<vtkRenderer>::New();
> > renderer->AddActor(plot);
> >
> > vtkSmartPointer<vtkRenderWindow> renderWindow =
> > vtkSmartPointer<vtkRenderWindow>::New();
> > renderWindow->AddRenderer( renderer );
> > renderWindow->SetSize(640, 480);
> >
> > vtkSmartPointer<vtkRenderWindowInteractor> interactor =
> > vtkSmartPointer<vtkRenderWindowInteractor>::New();
> > interactor->SetRenderWindow( renderWindow );
> >
> > // Initialize the event loop and then start it
> > interactor->Initialize();
> > interactor->Start();
> >
> >
> > return EXIT_SUCCESS;
> > }
> >
> >
> > On Thu, Jan 7, 2010 at 2:29 PM, michiel mentink
> > <michael.mentink at st-hughs.ox.ac.uk> wrote:
> >>>
> >>> Dear David,
> >>
> >> thank you for the example, there were some things that were different:
> >> this bit in the code I certainly coded differently than in the example:
> >>
> >> histogram->SetComponentExtent(0, 4000, 0, 0, 0, 0);
> >> histogram->SetComponentOrigin(0, 0, 0);
> >> histogram->SetComponentSpacing(0.16, 0.16, 3.26); // component
> spacing:
> >> depends on spacing of input volume
> >>
> >> I'm still a bit confused about the componentspacing.. as described
> above,
> >> I assumed it to be dependent on the input volume,
> >> but it is not???
> >>
> >> Anyway, I've extended your example a bit with writing the corresponding
> >> intensity levels to a file, for opening in a spreadsheet program.
> >> I'm not sure if it's too basic to put in the Examples section, but it
> >> helped me and maybe someone else could benefit from it too.
> >>
> >>
> >> Michael
> >>
> >>
> >> #include <vtkActor.h>
> >> #include <vtkImageAccumulate.h>
> >> #include <vtkImageData.h>
> >> #include <vtkImageExtractComponents.h>
> >> #include <vtkJPEGReader.h>
> >> #include <vtkRenderer.h>
> >> #include <vtkRenderWindow.h>
> >> #include <vtkRenderWindowInteractor.h>
> >> #include <vtkSmartPointer.h>
> >> #include <vtkStdString.h>
> >> #include <vtkXYPlotActor.h>
> >> #include <vtkPointData.h>
> >>
> >> int main( int argc, char *argv[] )
> >> {
> >> // Handle the arguments
> >> if( argc < 2 )
> >> {
> >> vtkstd::cout << "Required arguments: filename.jpg, [optional ignore
> >> zero:] <y/n>" << vtkstd::endl;
> >> return EXIT_FAILURE;
> >> }
> >>
> >> int ignoreZero = 0;
> >> if( argc == 3 )
> >> {
> >> vtkStdString ignore = argv[2];
> >> cout << ignore << endl;
> >> if( ignore == "y" || ignore == "Y" )
> >> {
> >> ignoreZero = 1;
> >> }
> >> }
> >>
> >> // Read a jpeg image
> >> //
> >> vtkSmartPointer<vtkJPEGReader> reader =
> >> vtkSmartPointer<vtkJPEGReader>::New();
> >> if( !reader->CanReadFile( argv[1] ) )
> >> {
> >> vtkstd::cout << "Error: cannot read " << argv[1] << vtkstd::endl;
> >> return EXIT_FAILURE;
> >> }
> >> reader->SetFileName( argv[1] );
> >> reader->Update();
> >>
> >> int numComponents =
> reader->GetOutput()->GetNumberOfScalarComponents();
> >> if( numComponents > 3 )
> >> {
> >> vtkstd::cout << "Error: cannot process an image with " <<
> >> numComponents << " components!" << vtkstd::endl;
> >> return EXIT_FAILURE;
> >> }
> >>
> >> // Create a vtkXYPlotActor
> >> //
> >> vtkSmartPointer<vtkXYPlotActor> plot =
> >> vtkSmartPointer<vtkXYPlotActor>::New();
> >> plot->ExchangeAxesOff();
> >> plot->SetLabelFormat( "%g" );
> >> plot->SetXTitle( "Level" );
> >> plot->SetYTitle( "Frequency" );
> >> plot->SetXValuesToValue();
> >>
> >> double xmax = 0.;
> >> double ymax = 0.;
> >>
> >> double colors[3][3] = {
> >> { 1, 0, 0 },
> >> { 0, 1, 0 },
> >> { 0, 0, 1 } };
> >>
> >> const char* labels[3] = {
> >> "Red", "Green", "Blue" };
> >>
> >> // Process the image, extracting and plotting a histogram for each
> >> component
> >> //
> >> //
> >>
> >> ofstream myfile;
> >> myfile.open ("histogram.txt");
> >> myfile << "Pixel intensities and their counts.\n";
> >>
> >> for( int i = 0; i < numComponents; ++i )
> >> {
> >> vtkSmartPointer<vtkImageExtractComponents> extract =
> >> vtkSmartPointer<vtkImageExtractComponents>::New();
> >> extract->SetInputConnection( reader->GetOutputPort() );
> >> extract->SetComponents( i );
> >> extract->Update();
> >>
> >> double range[2];
> >> extract->GetOutput()->GetScalarRange( range );
> >> vtkSmartPointer<vtkImageAccumulate> histogram =
> >> vtkSmartPointer<vtkImageAccumulate>::New();
> >> histogram->SetInputConnection( extract->GetOutputPort() );
> >> histogram->SetComponentExtent(
> >> 0,static_cast<int>(range[1])-static_cast<int>(range[0])-1,0,0,0,0 );
> >> histogram->SetComponentOrigin( range[0],0,0 );
> >> histogram->SetComponentSpacing( 1,0,0 );
> >> histogram->SetIgnoreZero( ignoreZero );
> >> histogram->Update();
> >>
> >> if( range[1] > xmax ) xmax = range[1];
> >> if( histogram->GetOutput()->GetScalarRange()[1] > ymax ) ymax =
> >> histogram->GetOutput()->GetScalarRange()[1];
> >>
> >> plot->AddInput( histogram->GetOutput() );
> >>
> >> if( numComponents > 1 )
> >> {
> >> plot->SetPlotColor(i,colors[i]);
> >> plot->SetPlotLabel(i,labels[i]);
> >> plot->LegendOn();
> >>
> >> myfile << "\n" << labels[i] << "\n\n";
> >> }
> >>
> >> unsigned int temp = (range[1]-1);
> >> unsigned int frequency[numLevels];
> >>
> >> std::cout<< "range: " << range[0] << " " << range[1] <<std::endl;
> >>
> >> unsigned int j;
> >>
> >> for(j=0;j<temp;j++){
> >> frequency[j]=0;
> >> frequency[j] =
> >> histogram->GetOutput()->GetPointData()->GetScalars()->GetTuple1(j);
> >> myfile << j << "\t" << frequency[j] << "\n";
> >> }
> >> }
> >>
> >> myfile.close();
> >>
> >> plot->SetXRange( 0, xmax );
> >> plot->SetYRange( 0, ymax );
> >>
> >> // Visualize the histogram(s)
> >> vtkSmartPointer<vtkRenderer> renderer =
> >> vtkSmartPointer<vtkRenderer>::New();
> >> renderer->AddActor(plot);
> >>
> >> vtkSmartPointer<vtkRenderWindow> renderWindow =
> >> vtkSmartPointer<vtkRenderWindow>::New();
> >> renderWindow->AddRenderer( renderer );
> >> renderWindow->SetSize(640, 480);
> >>
> >> vtkSmartPointer<vtkRenderWindowInteractor> interactor =
> >> vtkSmartPointer<vtkRenderWindowInteractor>::New();
> >> interactor->SetRenderWindow( renderWindow );
> >>
> >> // Initialize the event loop and then start it
> >> interactor->Initialize();
> >> interactor->Start();
> >>
> >>
> >> return EXIT_SUCCESS;
> >> }
> >>
> >>
> >>
> >>>
> >>> I reorganized the code a little bit, changed the input to a jpeg, and
> >>> posted an example in the "broken" section:
> >>> http://www.cmake.org/Wiki/VTK/Examples/Histogram
> >>>
> >>> Maybe this will double your chances of someone seeing it and figuring
> >>> out what is wrong :)
> >>>
> >>> Thanks,
> >>>
> >>> David
>
> Michiel,
>
> Dean has kindly been working on some examples:
>
> http://www.cmake.org/Wiki/VTK/Examples/Histogram
> http://www.cmake.org/Wiki/VTK/Examples/HistogramBarChart
>
> Have you done something that is not present in one of these? If so,
> can you explain the difference and we'll work together to create a
> third example.
>
> Thanks,
>
> David
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the VTK FAQ at:
> http://www.vtk.org/Wiki/VTK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.vtk.org/mailman/listinfo/vtkusers
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20100109/a4c8adf0/attachment.htm>
More information about the vtkusers
mailing list