GithubHelp home page GithubHelp logo

About Plot1D2D about silx HOT 10 CLOSED

silx-kit avatar silx-kit commented on July 19, 2024
About Plot1D2D

from silx.

Comments (10)

t20100 avatar t20100 commented on July 19, 2024

For the record, a few comments regarding the plot API (this does not change the need for refactoring and documentation of existing code):

  • Need for a plot API?
    • Pros: Be able to switch rendering backend (e.g. matplotlib, OpenGL...).
    • Cons: Support a subset of functionnalities, yet another plot API, add complexity to the code.
  • Some options regarding the API provided that there is no consensus on it:
    • Keep the API as it is in PyMca to support legacy.
    • Polish PyMca API but keep the general idea: limited changes in legacy.
    • Rename to use matplotlib like names:
      • Complete change of legacy code.
      • Expected to be easier for matplotlib users but it has some naming conflicts: matplotlib is PEP8 versus Qt CamelCase convention.
    • Write interaction directly over matplotlib (e.g. pan&zoom proof of concept: https://gist.github.com/t20100/e5a9ba1196101e618883):
      • Pros: Leverage all the features of matplotlib (with care in the interaction implementation)
      • Cons: Completely break PyMca's implementation, bound to matplotlib.
  • What about notebook/web support?

I think the plane is the second option since the beginning, but the last option should be kept in mind to provide a more generic option if needed.

For longer term, a few links about a common plot API over multiple backends:

from silx.

vasole avatar vasole commented on July 19, 2024

Well, it seems the only place at which there is no consensus is the DAU.

At the meeting it was pretty clear the different positions.

  • BCU illustrated by Matthias: "We are developers and we can adapt to anything. I do not see a major problem with what it is proposed". For information, BCU would like to have a "PyMca Scan Window"-like plotting tool in terms of functionality (to provide ROIs, fitting and so on) in their BCU web interfaces.
  • Scientists: "I want my life as easy as using a single command to plot and to have everything available including fitting, background substraction, integration and so on". Those operations are not part of any plotting API, but we have to provide a widget able to do all that.
  • DAU: Talking about the sex of the angels without keeping in mind our objective. The goal of silx is to simplify development and maintenance of applications by beamlines and scientists. That makes any reference to the notebook fools' gold: You cannot use the developed widgets into the notebook but you can use them from ipython, spyder, ... If we want to use the Web, we have to learn javascript. The goal is not to supply a matplotlib like API to the scientists (they already have matplotlib!), but to provide them with high level plotting widgets that implement their needs at almost no cost for them. Beamlines and scientists are the clients, not us, please keep it mind.

Yesterday I was at ID32. You should take a look at what has been developed there just "recycling" existing widgets. Nowhere was a complain about using an interface (API is a too heavy word in that context) to the plot different than matplotlib. Hey! They have to learn at minimum to instantiate an application, a widget, to show the widget and to start the application event loop. None of them are matplotlib commands. To learn a single command more (addCurve) to have everything they need for plotting curves or other one (addImage) for having everything they need for images does not seem a big price to be paid.

So, if the proposal is to keep a few commands for compatibility, to offer renamed ones for matplotlib compatibility while at the same time loosing the possibility to switch on-the-fly to a faster backend and not gaining anything over what it is existing, I think the answer is clear.

By the way, in the first of the links you supply, Almar gives you a clear hint ("We need a split"). Consider the proposed abstraction the user API in Almar's web page. One can spend as much time as desired developing a fully matplotlib-like interface just for at the end, having the only impact at the user side of changing basically one command. I think we have other priorities.

from silx.

srio avatar srio commented on July 19, 2024

May be redundant, but some of my ideas:

  • Time matters: the definition of the API should have been done 10 years ago and the library/widgets/tools available since Upgrade I. Conclusion: go as quick as possible, and keep the PyMca API or generaliza/improve it, but not reinvent it.
  • What is needed is powerful graphic widgets that manage all the graphics output to be used in new applications built with python. The "command line" simple command will come later, almost for free, if a powerful basement is first built. "Interaction" with the plot is the key.
  • I think matplotlib is not a model to follow. Unfortunately we have to go trough it because it is almost a standard for python-graphics. I think one of the handicaps of python is that there is not a basic powerful matplotlib-like graphics built in it. Matplotlib is slow, ugly (don't tell me that the default plots where sometimes you add +1.3e+8 hidden in an axis angle is nice and intuitive), and has a non-intuitive interface. Most of us want to get rid of matlab or other commercial packages, and we ended in cloning python to look like what we want to forget.
  • My wish is to have silx-graphics separated and installed separately of other silx components (i/o and other calculation tools). Operations integrated in silx-graphx (I like this name) should be standard in numpy (FFT, regression, etc.). May be pymca-marquard-levenberg fitting, but also this one could be kept as a minimal independent package. Like bricks to allow each one to build a personaized house. Once the "installation problem" is solved, I think is better to maintain small packages than a global solution to please the whole Universe.
  • And invest in training. Also in video.

from silx.

t20100 avatar t20100 commented on July 19, 2024

For early review/, here is the refactoring of PyMca PlotWidget: https://github.com/t20100/silx/tree/plot
It is a work in progress.

It aims at being compatible with PyMca's PlotWidget 'public API' as much as possible.

There is a script to play with it here: https://github.com/t20100/sandbox/blob/master/testPlotWidget.py
It can use either silx (default) or PyMca (python testPlotWidget.py pymca).

Added features

  • error bars
  • interaction continue outside plot area when mouse button is down (e.g., while zooming, drawing)
  • no flicking during interaction while plot content is changing
  • a few tests
  • a bootstrap of documentation
  • probably some bugs...

API Differences

The main difference is that it does not inherit from PluginLoader. To me this should be added to the toolbar providing plugins or on-demand as a composition of the Plot and the PluginLoader (rational: The plugins need the plot but not the otherway around).
The second difference is that it does not provide the printGraph method. I would like to have it as a separated class and provided in the user interface in the PlotWindow.
Other small API difference: addItem has an 'overlay' argument, get* methods to retrieve curve/image information return an additional element in the list they return (needed after splitting user provided info from plot parameters).

Proposals for API updates

Here is my API review/ideas.

Object oriented API

Keep a rather procedural API for the main things, but add OO API under it.
Basically, make add* methods return an object instead of a string key (the object legend) as of now.
At first, this object can provide information about the object (e.g., curve linestyle, user-defined information...).
It can also be used to uniquely identify a plot object and thus remove* method boils down to: remove(item) without giving the kind of item no matter how it is stored internally.
This paves the way for updating plot items through the returned plot objects, and adding listener on each plot object if needed.
It allows to add some functionalities without adding methods to the main API (e.g., show/hide objects, update...)

A proof of concept: https://github.com/t20100/sandbox/tree/master/plot

Qt like API typos

  • Rename isActiveCurveHandlingEnabled, enableActiveCurveHandling to
    isActiveCurveHandling, setActiveCurveHandling
  • Rename isYAxisInverted, invertYAxis to isYAxisInverted, setYAxisInverted or
    getYAxisOrientation, setYAxisOrientation
  • Rename keepDataAspectRatio to setKeepDataAspectRatio
  • Rename showGrid to setGridMode and add getGridMode
  • Add missing getters: getDefaultPlotPoints, getDefaultPlotLines

graph vs axis naming

  • Some methods use GraphX or GraphY (e.g. setGraphXLimits) while other are using XAxis or YAxis (e.g., isXAxisLogarithmic).
    Make the naming consistent.
  • Shorten names to X and Y (e.g., setXLimits, isXLogarithmic)?

add* methods

  • Rename insertMarker, insertXMarker, insertYMarker to addMarker, addXMarker, addYMarker to be inline with addCurve, addImage, addItem.
  • Remove add* methods replace argument in favor of an explicit call to clear.
    Or make replace argument have consistent default values (False).
    Now, False for addCurve and addItem, True for addImage.
  • Change add* behavior when legend argument is not provided.
    Now addCurve, addImage and addItem set it to a default value, and insert_Marker set it to an used value.
    Make all add_ methods find an unused value when legend is not provided.
    As plot objects are stored in dictionaries, this makes the behaviors of add* and insert*Marker different.
    For example: 2 calls to addCurve without legend, result in a single curve being finally added to the plot (the first added one being removed by the second), while 2 calls to insertMarker without legend, result in 2 markers being added.
  • addImage: remove pixmap argument and add a mask argument to provide a mask array the same size as the data image.
  • addImage: change xScale=(x origin, x scale) and yScale=(y origin, y scale) arguements to origin=(x origin, y origin) and scale=(x scale, y scale)

clear and remove methods

  • Replace methods: clear(), clearCurves(), clearImages(), clearItems(), clearMarkers() with clear(kind='all') with kind the type of items to remove.
    • Pros: less methods in API and clear() most likely the main one being called.
  • Replace methods: removeCurve(legend, replot=True), removeImage(legend, replot=True), removeItem(legend, replot=True), removeMarker(legend, replot=True) with remove(legend, kind, replot=True)
    • Pros: less methods in API
    • Cons: need to provide kind, as the plot is storing each kind of plot items in separate dictionaries (unless using objects instead of string key as add* methods result).

replot

  • Remove replot argument from all methods.
  • Provide an autoreplot feature that automatically handle replot internally using dirty flagging in the Plot and Qt event loop, with the possibility to disable autoreplot and explicitly handle it.

interaction

  • Replace isDrawModeEnabled, setDrawModeEnabled, getDrawMode, isZoomModeEnabled, setZoomModeEnabled by getInteractiveMode, setInteractiveMode.
    Pros: Avoid to have interference between methods (setting draw mode disable zoom mode (and vice versa)) + allow to add interaction modes without adding new methods.
  • Add an interactive mode where no interaction is performed, but all events
    are forwared to the callback. This allows for extension.
  • Add a pan and zoom mode

hide methods

Now only available for curve: Remove this feature?
Or add hide for image, item, markers.
If using object oriented plot objects, this can be available as a visible attribute of objects.

get plot content

  • getAllCurves, getCurve, getMonotonicCurves, getImage returns plot object information as a list, make it return objects (as add* methods)
  • Rename getAllCurves to getCurves
  • Add getImages, getItem(s), getMarker(s)

Misc.

  • Add different signals for each kind of plot events (and keep the general one).
  • Remove **kw from all methods

colormap

Now defined as a dict with 'name', 'normalization', 'autoscale', 'vmin', 'vmax'.
vmin and vmax are ignored if autoscale is True.
'autoscale' is not necessary, it can be enable when 'vmin' and/or 'vmax' are None.

from silx.

vasole avatar vasole commented on July 19, 2024

Some quick comments to explain the rationale behind some things and the proposed changes

Qt like API typos

  • I do not see major problems with the proposed changes

graph versus axis naming

  • The origin of that naming was to be able to distinguish between data limits and graph limits

add* methods

  • Rename OK
  • I do not see a major problem with having different treatment for images (replace=True) than for curves (replace=False). Both things are not the same. Most graphics APIs allow you (by default) to visualize several curves while (by default) showing only one image ... Example: plot versus imshow
  • OK to change the behavior for insertMarker, but I find the proposed behavior more dangerous than the previous one. If one provides a default name, one is sure of not accumulating objects in the plot, If one keeps replace=False for curves and replace=True for images, the risk is minimal and the proposed behavior is fine.
  • Big objection to the removal of the pixmap.
    • In image visualization I can see the experimental data, its pixmap representation and an associated mask. If one receives data and a pixmap, that pixmap is to be used and it is not to be calculated. Furthermore, when we read an actual image we only have the pixmap. How are you going to visualize it? You have collected data on a raster scan and you have a picture of the scanned region but with your removal proposal you cannot show the picture.
    • Probably you are going to have the associated pixmap somewhere internally. So, what is really the problem to accept it?
  • OK for the change to origin and scale.

clear and remove methods

  • Is it really so hard to maintain your clear(kind="all") (equivalent of current clear) with the existence of clearCurves() that just makes a call to clear(kind="curves")? I think it is asking for unnecessary refactoring. One can implement clear(kind="all") while keeping the others.as shortcuts to clear.
  • I see a big drawback on having to provide "kind". However, there is no problem if there is a default for kind. For instance kind="all" would allow to delete a family of objects (scatter plots, images, markers, ...) associated to a certain visualization.

replot

  • Sounds fine.

hide methods

  • It is quite convenient when you have many curves to be able to toggle visibility. That is not usually the case with the other items. I am more in favor of adding the feature to the other items than to remove it from the curves.

interaction

  • Panning should be able while drawing
  • Zooming using other thing than the mouse too

The goal is to be able to pan and (less important) zoom while drawing a polygonal mask.

get plot content

  • If you intend to change getAllCurves to return objects and you also intend to rename it, then keep the old getAllCurves as it is and implement getCurves, not rename something to do something different. Then all the proposed changes go smoothly and again, you do not ask for unnecessary refactoring.

Misc

  • I have no defined opinion on those changes.I see advantages and disadvantages.but I do not see a clear winner.

Colormap

  • To have vmin and vmax as arguments was allow to avoid unnecessary recalculation of vmin and vmax
  • It also allowed "stupid" colormap widgets to be agnostic about the data, That is the reason of having vmin, vmax, dataMin, dataMax.
  • If we are going to pass the data to the colormap widgets in order to be able to calculate histogram based colormaps, previous points loose much of their interest.

from silx.

vasole avatar vasole commented on July 19, 2024

API differences

Just a comment.

  • The main goal of having plugin loader as part of the base was to be able to provide easy testing of the plugins because Qt was not needed. I guess now that feature is lost.

from silx.

vasole avatar vasole commented on July 19, 2024

I get a FutureWarning on line 126 of BackendMatplotlib.py

FutureWarning: "comparison to 'None' will result in an elementwise object comparison in the future"

from silx.

vasole avatar vasole commented on July 19, 2024

Draw line raise NotImplementedError: Unsupported item shape line

from silx.

vasole avatar vasole commented on July 19, 2024

Test error bars gives a warning: CANNOT CALCULATE LIMITS

from silx.

t20100 avatar t20100 commented on July 19, 2024

For the plugins, it is lost for now, but can be composed with Plot class.
I added a dummy backend to the Plot which allows to run the Plot headless.

Fixed the raised issues.

from silx.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.