MultiplePlots
Repository source: MultiplePlots
Description¶
Display multiple plots by using viewports in a single render window.
In this case, we display two graphs side-by-side.
The difference between setting a background in the renderer and setting the chart background is shown.
Note
This example was prompted by this discussion vtk chart background shifted towards origin.
Other languages
See (Python), (PythonicAPI)
Question
If you have a question about this example, please use the VTK Discourse Forum
Code¶
MultiplePlots.cxx
#include <vtkAxis.h>
#include <vtkBrush.h>
#include <vtkChartXY.h>
#include <vtkContextActor.h>
#include <vtkContextScene.h>
#include <vtkFloatArray.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPlotPoints.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkTable.h>
#include <vtkVersion.h>
#include <array>
#include <cmath>
#include <vector>
#if VTK_VERSION_NUMBER >= 90220220630ULL
#define VTK_HAS_SETCOLORF 1
#endif
int main(int, char*[])
{
vtkNew<vtkNamedColors> colors;
vtkNew<vtkRenderWindow> renWin;
renWin->SetWindowName("MultiplePlots");
vtkNew<vtkRenderWindowInteractor> iRen;
iRen->SetRenderWindow(renWin);
// Setup the viewports
auto gridDimensionsX = 2;
auto gridDimensionsY = 1;
auto rendererSizeX = 320;
auto rendererSizeY = 240;
renWin->SetSize(rendererSizeX * gridDimensionsX,
rendererSizeY * gridDimensionsY);
std::cout << rendererSizeX * gridDimensionsX << " "
<< gridDimensionsY * gridDimensionsY << std::endl;
std::vector<std::array<double, 4>> viewPorts;
for (auto row = 0; row < gridDimensionsY; ++row)
{
for (auto col = 0; col < gridDimensionsX; ++col)
{
// index = row * gridDimensionsX + col
// (xmin, ymin, xmax, ymax)
viewPorts.push_back(std::array<double, 4>{
static_cast<double>(col) / gridDimensionsX,
static_cast<double>(gridDimensionsY - (row + 1.0)) / gridDimensionsY,
static_cast<double>(col + 1.0) / gridDimensionsX,
static_cast<double>(gridDimensionsY - static_cast<double>(row)) /
gridDimensionsY});
}
}
// Link the renderers to the viewports.
vtkNew<vtkRenderer> leftRenderer;
leftRenderer->SetBackground(colors->GetColor3d("AliceBlue").GetData());
leftRenderer->SetViewport(viewPorts[0].data());
renWin->AddRenderer(leftRenderer);
vtkNew<vtkRenderer> rightRenderer;
rightRenderer->SetBackground(colors->GetColor3d("Lavender").GetData());
rightRenderer->SetViewport(viewPorts[1].data());
renWin->AddRenderer(rightRenderer);
// Create the charts.
vtkNew<vtkChartXY> leftChart;
vtkNew<vtkContextScene> leftChartScene;
vtkNew<vtkContextActor> leftChartActor;
leftChartScene->AddItem(leftChart);
leftChartActor->SetScene(leftChartScene);
leftRenderer->AddActor(leftChartActor);
leftChartScene->SetRenderer(leftRenderer);
auto xAxis = leftChart->GetAxis(vtkAxis::BOTTOM);
xAxis->GetGridPen()->SetColor(colors->GetColor4ub("LightGrey"));
xAxis->SetTitle("x");
auto yAxis = leftChart->GetAxis(vtkAxis::LEFT);
yAxis->GetGridPen()->SetColor(colors->GetColor4ub("LightGrey"));
yAxis->SetTitle("cos(x)");
#if VTK_HAS_SETCOLORF
leftChart->GetBackgroundBrush()->SetColorF(
colors->GetColor4d("MistyRose").GetData());
#else
leftChart->GetBackgroundBrush()->SetColor(
colors->GetColor4d("MistyRose").GetData());
#endif
leftChart->GetBackgroundBrush()->SetOpacityF(0.4);
leftChart->SetTitle("Cosine");
vtkNew<vtkChartXY> rightChart;
vtkNew<vtkContextScene> rightChartScene;
vtkNew<vtkContextActor> rightChartActor;
rightChartScene->AddItem(rightChart);
rightChartActor->SetScene(rightChartScene);
rightRenderer->AddActor(rightChartActor);
rightChartScene->SetRenderer(rightRenderer);
xAxis = rightChart->GetAxis(vtkAxis::BOTTOM);
xAxis->GetGridPen()->SetColor(colors->GetColor4ub("LightCyan"));
xAxis->SetTitle("x");
yAxis = rightChart->GetAxis(vtkAxis::LEFT);
yAxis->GetGridPen()->SetColor(colors->GetColor4ub("LightCyan"));
yAxis->SetTitle("sin(x)");
#if VTK_HAS_SETCOLORF
rightChart->GetBackgroundBrush()->SetColorF(
colors->GetColor4d("Thistle").GetData());
#else
rightChart->GetBackgroundBrush()->SetColor(
colors->GetColor4d("Thistle").GetData());
#endif
rightChart->GetBackgroundBrush()->SetOpacityF(0.4);
rightChart->SetTitle("Sine");
// Create a table with some points in it.
vtkNew<vtkTable> table;
vtkNew<vtkFloatArray> arrX;
arrX->SetName("X Axis");
table->AddColumn(arrX);
vtkNew<vtkFloatArray> arrC;
arrC->SetName("Cosine");
table->AddColumn(arrC);
vtkNew<vtkFloatArray> arrS;
arrS->SetName("Sine");
table->AddColumn(arrS);
// Fill in the table with some example values.
auto numPoints = 40;
auto inc = 7.5 / (numPoints - 1.0);
table->SetNumberOfRows(numPoints);
for (int i = 0; i < numPoints; ++i)
{
table->SetValue(i, 0, i * inc);
table->SetValue(i, 1, cos(i * inc));
table->SetValue(i, 2, sin(i * inc));
}
auto ptColor = colors->GetColor4ub("Black");
auto points = leftChart->AddPlot(vtkChart::POINTS);
points->SetInputData(table, 0, 1);
points->SetColor(ptColor.GetRed(), ptColor.GetGreen(), ptColor.GetBlue(),
ptColor.GetAlpha());
points->SetWidth(1.0);
dynamic_cast<vtkPlotPoints*>(points)->SetMarkerStyle(vtkPlotPoints::CROSS);
points = rightChart->AddPlot(vtkChart::POINTS);
points->SetInputData(table, 0, 2);
points->SetColor(ptColor.GetRed(), ptColor.GetGreen(), ptColor.GetBlue(),
ptColor.GetAlpha());
points->SetWidth(1.0);
dynamic_cast<vtkPlotPoints*>(points)->SetMarkerStyle(vtkPlotPoints::PLUS);
renWin->Render();
iRen->Initialize();
iRen->Start();
return EXIT_SUCCESS;
}
CMakeLists.txt¶
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(MultiplePlots)
find_package(VTK COMPONENTS
ChartsCore
CommonColor
CommonCore
CommonDataModel
InteractionStyle
RenderingContext2D
RenderingContextOpenGL2
RenderingCore
RenderingFreeType
RenderingGL2PSOpenGL2
RenderingOpenGL2
)
if (NOT VTK_FOUND)
message(FATAL_ERROR "MultiplePlots: Unable to find the VTK build folder.")
endif()
# Prevent a "command line is too long" failure in Windows.
set(CMAKE_NINJA_FORCE_RESPONSE_FILE "ON" CACHE BOOL "Force Ninja to use response files.")
add_executable(MultiplePlots MACOSX_BUNDLE MultiplePlots.cxx )
target_link_libraries(MultiplePlots PRIVATE ${VTK_LIBRARIES}
)
# vtk_module_autoinit is needed
vtk_module_autoinit(
TARGETS MultiplePlots
MODULES ${VTK_LIBRARIES}
)
Download and Build MultiplePlots¶
Click here to download MultiplePlots and its CMakeLists.txt file. Once the tarball MultiplePlots.tar has been downloaded and extracted,
cd MultiplePlots/build
If VTK is installed:
cmake ..
If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:
cmake -DVTK_DIR:PATH=/home/me/vtk_build ..
Build the project:
make
and run it:
./MultiplePlots
WINDOWS USERS
Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.