[vtkusers] plotting bar chart with vtkBarChartActor and vtkXYPlotActor

David Doria daviddoria+vtk at gmail.com
Fri Jan 8 19:08:44 EST 2010


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



More information about the vtkusers mailing list