[vtkusers] Updating data in a vtkChartXY

Marcus D. Hanwell marcus.hanwell at kitware.com
Thu Dec 3 20:12:09 EST 2015


On Tue, Dec 1, 2015 at 1:29 PM, Nicolas Bigaouette
<nbigaouette at gmail.com> wrote:
> Hi all,
>
> I'm using vtkChartXY to plot some data.
>
> I now need to update the data that is displayed but I'm having trouble doing
> so.
>
> Some people were able to call ClearPlots() to recreate the plot. This is a
> bit problematic since I have multiple lines on my figure. I was able to
> refactor my code to store the line properties (color, width, etc.) and
> re-apply them after they are added back to the figure. See for example
> those:

I was just checking into this, because you shouldn't need to call
ClearPlots at all... I wrote code to determine when to update the
cached data, pack it, perform any necessary conversions. We try to be
conservative as it can be quite expensive, and on re-examining I
wonder if we missed an importan criteria.

That said, I changed a Python test, an dwas able to modify the data in
place in the vtkFloatArray objects, then call Modified() on the
vtkTable, and upon calling Render() on the view I saw the updated
data.

Does that not work for you? We check if the table and some other
things changed since our last build of the cache, the relevant code is
in vtkPlotPoints.cxx for both line and point plots.
>
> I have three questions.
>
> 1) Does the ClearPlots() frees all memory used? What happens to the previous
> linePtr? Are they free? If I update the figure thousands of time for a
> "large" number of lines, is there a risk of a memory leak somewhere? How to
> properly free the resources?

It should, vtkObject derived classes are implicitly reference counted.
There is always a risk of a memory leak due to an undiscovered bug,
but this should not leak. We use a flag to highlight leaks when
testing, and so you should be pretty safe.
>
> 2) Is there a better way to update a single line out of many? Without memory
> leaks?

I think calling Modified() on the table will likely cause all of your
plots to update their internal cache. I think this porbably needs to
be improved to look at the mtime of the component arrays rather than
the top-level table, but you should be able to modify the array in
place, call Modified on the containing table, and Render on the view.
>
> 3) Most importantly, this breaks setting the axis range. For example, doing
> this after a line update:
>>
>> chart->GetAxis(vtkAxis::BOTTOM)->SetRange(minval, maxval);
>
> will change the axis values, but the lines look exactly the same as before
> this "zooming".

You can change the axis to vtkAxis::FIXED to cause that axis to never
rescale, it is SetBehavior or similar method on vtkAxis.
>
> Maybe it has something to do with how I put everything together:
>>
>> vtkSmartPointer<vtkRenderer> vRenderer =
>> vtkSmartPointer<vtkRenderer>::New();
>> vtkGenericOpenGLRenderWindow *renderWindow = GetRenderWindow();
>> renderWindow->AddRenderer(renderer);
>> vtkSmartPointer<vtkContextScene> chartScene =
>> vtkSmartPointer<vtkContextScene>::New();
>> vtkSmartPointer<vtkContextActor> chartActor =
>> vtkSmartPointer<vtkContextActor>::New();
>> vtkSmartPointer<vtkChartXY> chart = vtkSmartPointer<vtkChartXY>::New();
>> chartScene->AddItem(chart);
>> chartActor->SetScene(chartScene);
>> renderer->AddActor(chartActor);
>
I would use vtkNew to reduce the repetition of class names in
initialization, but hopefully what I described above will be helpful.

Marcus


More information about the vtkusers mailing list