Ticket #2656 (closed: fixed)
Add the ability to interact with curves on an existing plot
Reported by: | Nick Draper | Owned by: | Russell Taylor |
---|---|---|---|
Priority: | major | Milestone: | Release 2.0 |
Component: | MantidPlot | Keywords: | |
Cc: | Blocked By: | ||
Blocking: | Tester: | Nick Draper |
Description
Lots of this would be useful, but I can see it is a lot, we may have to cherry pick or split into separate tickets.
From QTIplot Handbook:
Working with 2D curves You can then add or remove curves to or from this layer: l.insertCurve(table, Ycolumn, type=Layer.Scatter, int startRow = 0, int endRow = -1)# returns a reference to the inserted curve l.insertCurve(table, Xcolumn, Ycolumn, type=Layer.Scatter, int startRow = 0, int endRow = -1)# returns a reference to the inserted curve l.addCurve(table, column, type=Layer.Line, lineWidth = 1, symbolSize = 3, startRow = 0, endRow = -1)# returns True on success l.addCurves(table, (2,4), type=Layer.Line, lineWidth = 1, symbolSize = 3, startRow = 0, endRow = -1)# returns True on success l.removeCurve(curveName) l.removeCurve(curveIndex) l.removeCurve(curveReference) l.deleteFitCurves() It is possible to change the order of the curves inserted in a layer using the following function: l.changeCurveIndex(int oldIndex, int newIndex) Sometimes, when performing data analysis, one might need the curve title. It is possible to obtain it using the method below: title = l.curveTitle(curveIndex) It is possible to get a reference to a curve on the layer l using it's index or it's title, like shown below: c = l.curve(curveIndex) c = l.curve(curveTitle) dc = l.dataCurve(curveIndex) Please, keep in mind the fact that the above methods might return an invalid reference if the curve with the specified index/title is not a PlotCurve or a DataCurve object, respectively. For example, an analytical function curve is a PlotCurve but not a DataCurve and spectrograms are a completely different type of plot items which are neither PlotCurves nor DataCurves. Use the following function to change the axis attachment of a curve: l.setCurveAxes(number, x-axis, y-axis) where number is the curve's number, x-axis is either 0 or 1 (bottom or top) and y-axis is either 0 or 1 (left or right). In case you need the number of curves on a layer, you can get it with l.numCurves() Once you have added a curve to a 2D plot, you can fully customize it's appearance: l = newGraph().activeLayer() l.setAntialiasing() c = l.insertCurve(table("Table1"), "Table1_2", Layer.LineSymbols) c.setPen(QtGui.QPen(Qt.red, 3)) c.setBrush(QtGui.QBrush(Qt.darkYellow)) c.setSymbol(PlotSymbol(PlotSymbol.Hexagon, QtGui.QBrush(Qt.yellow), QtGui.QPen(Qt.blue, 1.5), QtCore.QSize(15, 15))) It is possible to change the number of symbols to be displayed for a curve using the function below. This option can be very usefull for very large data sets: c.setSkipSymbolsCount(3) print c.skipSymbolsCount() An alternative way of customizing a curve is by using the functions below: l.setCurveLineColor(int curve, int color) # uses the index of the colors in the default QtiPlot color list: 0 = black, 1 = red, 2 = green, etc... l.setCurveLineStyle(int curve, Qt::PenStyle style) l.setCurveLineWidth(int curve, double width) You can also define a global color policy for the plot layer using the following convenience functions: l.setGrayScale() l.setIndexedColors() # uses the colors in the default QtiPlot color list: 0 = black, 1 = red, 2 = green, etc... You can display labels showing the y values for each data point in a DataCurve: c.setLabelsColumnName("Table1_2") c.setLabelsOffset(50, 50) c.setLabelsColor(Qt.red) c.setLabelsFont(QtGui.QFont("Arial", 14)) c.setLabelsRotation(45) c.loadData() # creates the labels and updates the display and, of course, you can disable them using: c.clearLabels() l.replot() # redraw the plot layer object If you need to change the range of data points displayed in a DataCurve you can use the following methods: c.setRowRange(int startRow, int endRow) c.setFullRange() Also, you can hide/show a plot curve via: c.setVisible(bool on) In case you need to get information about the data stored in the curve, you have at your disposal the functions below: points = c.dataSize() for i in range (0, points): print i, "x = ", c.x(i), "y = ", c.y(i) print c.minXValue() print c.maxXValue() print c.minYValue() print c.maxYValue() Curve symbols Here's how you can customize the plot symbol used for a 2D plot curve c: s = c.symbol() s.setSize(QtCore.QSize(7, 7))# or s.setSize(7) s.setBrush(QtGui.QBrush(Qt.darkYellow)) s.setPen(QtGui.QPen(Qt.blue, 3)) s.setStyle(PlotSymbol.Diamond) l.replot() # redraw the plot layer object The symbol styles available in QtiPlot are: 0 PlotSymbol.NoSymbol 1 PlotSymbol.Ellipse 2 PlotSymbol.Rect 3 PlotSymbol.Diamond 4 PlotSymbol.Triangle 5 PlotSymbol.DTriangle 6 PlotSymbol.UTriangle 7 PlotSymbol.LTriangle 8 PlotSymbol.RTriangle 9 PlotSymbol.Cross 10 PlotSymbol.XCross 11 PlotSymbol.HLine 12 PlotSymbol.VLine 13 PlotSymbol.Star1 14 PlotSymbol.Star2 15 PlotSymbol.Hexagon It is also possible to define a custom image as the plot symbol for a curve: g = newGraph().activeLayer() c = g.addFunction("cos(x)", 0, 10, 20) c.setSymbol(ImageSymbol("qtiplot/manual/html/icons/help.png")) Here's a short script showing how to draw a custom plot symbol and assign it to a curve: pix = QtGui.QPixmap(QtCore.QSize(11, 11)) pix.fill(Qt.transparent) p = QtGui.QPainter(pix) r = QtCore.QRect(0, 0, 10, 10) p.drawEllipse(r) p.setPen(QtGui.QPen(Qt.red)) p.drawLine(5, 0, 5, 10) p.drawLine(0, 5, 10, 5) p.end() g = newGraph().activeLayer() c = g.addFunction("sin(x)", 0, 10, 20) c.setSymbol(ImageSymbol(pix))
Change History
comment:2 Changed 9 years ago by Nick Draper
- Milestone changed from Iteration 29 to Iteration 30
"New" tickets moved at the code freeze of iteration 29
comment:3 Changed 9 years ago by Nick Draper
- Milestone changed from Iteration 30 to Iteration 31
Bulk move of tickets to iteration 31 at the iteration 30 code freeze
comment:5 Changed 9 years ago by Russell Taylor
Add ability to set a curve's symbol, pen & brush via python.
QwtSymbol is exposed as PlotSymbol and allows all aspects of the symbol to be customised. The setCurvePen method acts on the characteristics of the line and offers more advanced options than the setCurveLineColor/Style/Width methods. setCurveBrush acts on the area beneath a curve (e.g. fill colour, style...) Re #2656.
Changeset: f54a051d588704821b07568a685f0f5ce9d15af3
comment:6 Changed 9 years ago by Russell Taylor
Add a Graph::insertCurve overload for adding Mantid curves. Re #2656.
Takes a workspace name and index and adds a 1D curve. Exposed this method to python, along with the overload that takes just the Y column name of a table.
Changeset: fa814ca588355e13c24300fcdca984b7123095a4
comment:7 Changed 9 years ago by Russell Taylor
Later, I'll intercept the insertCurve method so that a reference to workspace can be given instead of (or as well as) the name.
comment:8 Changed 9 years ago by Russell Taylor
Add curveTitle & setCurveAxes to python layer objects. Re #2656.
Changeset: 31754e5cc55e8e76c187844e6a2b8fc82164176d
comment:9 Changed 9 years ago by Russell Taylor
Add the ability to use a custom symbol on a plot. Re #2656.
Seems slightly frivolous, but it was easy so why not. Involved bringing in the ImageSymbol class from today's QtiPlot and exposing to python. A custom symbol can be loaded from an image file or drawn using the QPixmap class.
Changeset: 5a9bd8c84616908d3c629b984a89ed8d5b6bc2ce
comment:10 Changed 9 years ago by Russell Taylor
Indentation fixes only. Re #2656.
Changeset: 2ffcd8ea77f936494b8476297f999697b2c11fc9
comment:11 Changed 9 years ago by Russell Taylor
Indentation/formatting only. Re #2656.
Changeset: b14f31ca337df4e06681a70951cfb57ba9b4f662
comment:12 Changed 9 years ago by Russell Taylor
Add possibility to draw only every n'th symbol on a 1D plot. Re #2656.
Back-ported in from today's QtiPlot.
Changeset: 19e2007c71dc94d75f0d677e60a78475a532e4d4
comment:13 Changed 9 years ago by Russell Taylor
Retain skipped symbols in Mantid curves on reloading a saved project.
Re #2656.
Changeset: b90293339ffe2300c6d19d277a96b5b747854281
comment:14 Changed 9 years ago by Russell Taylor
Indentation/formatting changes only. Re #2656.
Changeset: d9e9c1fa3f62e9520446e8297ca9c392d5824b5f
comment:15 Changed 9 years ago by Russell Taylor
Draw error bars only when symbol is drawn (non-Mantid curves only).
Re #2656. Will address greater control of when error bars are drawn, including for Mantid curves under #2657.
Changeset: aa78ad5c34ca194678e2301c2c5ca56379108148
comment:16 Changed 9 years ago by Russell Taylor
Add setGrayScale & setIndexedColors methods to Graph. Re #2656.
Allows switching all curves on a plot between grayscale and colour. Exposed to python.
Changeset: cebbed0e01455b24c899b2499ba72c91b5f63425
comment:17 Changed 9 years ago by Russell Taylor
Expose arguments on insertCurve that allow plotting only a range...
...of rows from a table. Re #2656.
Changeset: 1130ba4c27e17537656b6fe0e288dbfea3480d06
comment:18 Changed 9 years ago by Russell Taylor
Almost everything in the description has now been implemented, with a few exceptions.
The most notable of these is that I decided not to expose the curve classes themselves. However, most of the actions can be accomplished through calling methods on Graph instead - e.g. l.setCurveSkipSymbolsCount(curveNum,3) instead of c.setSkipSymbolsCount(e).
The following items are missing:
- Changing a curve's index (l.changeCurveIndex)
- Showing and customising labels on individual points
- Changing the range of points (e.g. rows of a table) that are plotted
- Hiding a curve (except by removing it)
- Retrieving the data values/min/max of a curve
- Retaining a custom symbol (from file or 'hand drawn') after saving & reloading a project
I still need to update our wiki documentation before closing this ticket.
comment:19 Changed 9 years ago by Russell Taylor
Have Layer.insertCurve accept a WorkspaceProxy. Re #2656.
Also a bit more pertaining to #1037.
Changeset: 6c05dfba404e7a1f0b6965573c85ad02e6a6a78d
comment:20 Changed 9 years ago by Russell Taylor
- Status changed from accepted to verify
- Resolution set to fixed
comment:21 Changed 9 years ago by Russell Taylor
- Status changed from verify to reopened
- Resolution fixed deleted
Forgot that I still need to do the documentation.....
comment:23 Changed 9 years ago by Nick Draper
- Milestone changed from Iteration 32 to Iteration 33
Moved to iteration 33 at iteration 32 code freeze
comment:24 Changed 9 years ago by Russell Taylor
- Milestone changed from Iteration 33 to Iteration 32
comment:25 Changed 9 years ago by Russell Taylor
- Status changed from accepted to verify
- Resolution set to fixed
Documentation is at: http://www.mantidproject.org/MantidPlot:_Working_with_1D_curves
comment:26 Changed 9 years ago by Russell Taylor
A small fix to pass through call. Re #2656.
Changeset: 4be9f43c5ead234ccb30a0805cc3876e87756663
comment:27 Changed 9 years ago by Nick Draper
- Status changed from verify to verifying
- Tester set to Nick Draper
comment:28 Changed 9 years ago by Nick Draper
- Status changed from verifying to closed
Tested on Windows 7 64 bit
particularly liked this one
g = newGraph().activeLayer() g.addFunction("cos(x)", 0, 10, 20) g.setCurveSymbol(0, ImageSymbol("C:/Mantid/Documents/Images/Mantid Icon32.gif"))
comment:29 Changed 5 years ago by Stuart Campbell
This ticket has been transferred to github issue 3503
Bulk move of tickets at the end of iteration 28