vtkChartXY纵横比

时间:2018-12-18 11:57:30

标签: charts vtk

我有一个带有vtkChartXY的简单图,如本例所示:

https://www.vtk.org/Wiki/VTK/Examples/Cxx/Plotting/ScatterPlot

如果视口的大小发生变化,如何设置轴的固定长宽比?

1 个答案:

答案 0 :(得分:1)

我认为您不能使用vtkChartXY来做到这一点。通常,vtkChart*类似乎很不灵活。不使用它们意味着您必须自己定义一些东西,但是至少,您可以控制一切。所以这是一种方法。此解决方案在具有固定纵横比的轴系统上同时显示了散点图和线图:

#!/usr/bin/env python3

from vtk import *
import sys
from math import sin, pi

def main():
    # Use named colors
    colors = vtk.vtkNamedColors()

    # ====== data to plot (discretised sine) ======
    points = vtkPoints()

    N_points = 20
    for i in range(N_points):
        xi = i*2*pi/(N_points-1)
        yi = sin(xi)
        points.InsertNextPoint(xi, yi, 0.)

    # Add points to a polydata object
    data = vtkPolyData()
    data.SetPoints(points)

    # ====== Scatter plot: put a glyph (marker) at each point ======
    # Define a glyph
    glyph = vtk.vtkGlyphSource2D()
    glyph.SetGlyphTypeToCircle()
    glyph.SetResolution(20)
    glyph.SetScale(0.1)
    glyph.SetScale2(1)
    glyph.FilledOff()
    glyph.CrossOn()
    glyph.Update()

    # Use a glyph filter to modify the glyphs: where to place them, how to color them, etc.
    glypher = vtk.vtkGlyph3D()
    glypher.SetSourceConnection(0, glyph.GetOutputPort()) # what glyphs to draw
    glypher.SetInputData(data) # where to put the glyphs
    glypher.SetScaleFactor(1)
    glypher.Update()

    # Define a mapper, actor, and vtkPropItem for the scatter plot:
    glyphMapper = vtk.vtkPolyDataMapper()
    glyphMapper.SetInputConnection(glypher.GetOutputPort())
    glyphMapper.Update()

    glyphActor = vtkActor()
    glyphActor.SetMapper(glyphMapper)
    glyphActor.GetProperty().SetColor(colors.GetColor3d("black"))
    glyphActor.GetProperty().SetLineWidth(1)

    glyphItem = vtkPropItem() # for vtkContextArea
    glyphItem.SetPropObject(glyphActor)


    # ====== Line plot: define connections between the points ======
    line = vtkPolyLine()
    line.GetPointIds().SetNumberOfIds(N_points)
    for i in range(N_points):
        line.GetPointIds().SetId(i,i)

    # add the line to the vtkPolyData object data:
    lines = vtkCellArray() # need a cell array to contain data's lines
    lines.InsertNextCell(line)
    data.SetLines(lines)

    # Define a mapper, actor, and vtkPropItem for the line plot:
    linesMapper = vtkPolyDataMapper()
    linesMapper.SetInputData(data)
    linesMapper.SetColorModeToMapScalars()
    linesMapper.Update()

    linesActor = vtkActor()
    linesActor.GetProperty().SetColor(colors.GetColor3d("red"))
    linesActor.SetMapper(linesMapper)
    linesActor.GetProperty().SetLineWidth(2)

    linesItem = vtkPropItem() # for vtkContextArea
    linesItem.SetPropObject(linesActor)


    # ======= vtkContextArea: axes with set aspect ratio within which to place objects ======
    area = vtkContextArea()
    bounds = vtkBoundingBox()
    bounds.SetBounds(0, 2*pi, -1, 1, 0, 0)
    area.SetDrawAreaBounds(vtkRectd(bounds.GetBound(0), bounds.GetBound(2),
                                    bounds.GetLength(0), bounds.GetLength(1)))
    # Set aspect ratio of the x and y axes so that units on x and y have the same length:
    area.SetFixedAspect(bounds.GetLength(0) / bounds.GetLength(1))

    # area.GetAxis(vtkAxis.TOP).SetTitle("Top Axis")
    area.GetAxis(vtkAxis.BOTTOM).SetTitle("x")
    area.GetAxis(vtkAxis.LEFT).SetTitle("y = sin(x)")
    # area.GetAxis(vtkAxis.RIGHT).SetTitle("Right Axis")

    axisid = [vtkAxis.LEFT, vtkAxis.BOTTOM, vtkAxis.RIGHT, vtkAxis.TOP]
    for i in range(4):
        axis = area.GetAxis(axisid[i])
        axis.GetLabelProperties().SetColor(colors.GetColor3d("black"))
        axis.GetTitleProperties().SetColor(colors.GetColor3d("black"))
        axis.GetTitleProperties().BoldOff()

    area.GetDrawAreaItem().AddItem(glyphItem)
    area.GetDrawAreaItem().AddItem(linesItem)


    #----------------------------------------------------------------------------
    # Context2D initialization:
    view = vtkContextView()
    view.GetRenderer().SetBackground(colors.GetColor3d("white"))
    view.GetRenderWindow().SetSize(600, 300)
    view.GetRenderWindow().SetMultiSamples(0)
    view.GetInteractor().Initialize()
    view.GetScene().AddItem(area)
    view.GetInteractor().Start()    

if __name__ == '__main__':
    main()

运行此脚本将产生一个可调整大小的窗口,在该窗口中轴比率保持固定,此处一个x单位与一个y单位相同。 VTK 2D Scatter and line plot with fixed aspect ratio