vtkChartXY Соотношение сторон - PullRequest
       21

vtkChartXY Соотношение сторон

0 голосов
/ 18 декабря 2018

У меня есть простой график с vtkChartXY, как в этом примере:

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

Как я могу установить фиксированное соотношение сторон оси, если размер окна просмотра изменяется?

1 Ответ

0 голосов
/ 28 января 2019

Я не думаю, что вы можете сделать это, используя 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

...