我有一个带有vtkChartXY的简单图,如本例所示:
https://www.vtk.org/Wiki/VTK/Examples/Cxx/Plotting/ScatterPlot
如果视口的大小发生变化,如何设置轴的固定长宽比?
答案 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()