Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parasite axes #96

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open

Parasite axes #96

wants to merge 8 commits into from

Conversation

bsobhani
Copy link
Contributor

Added a class MatplotlibHostParasiteAxes for plotting multiple axes.

parasite_axes

This pull request just contains the class. To run tests I have just been adding "MatplotlibAxes = MatplotlibHostParasiteAxes" to the end of _matplotlib_axes.py.

@danielballan
Copy link
Member

The next step would be to add a ParasiteAxes Model and move some of the "brains" here into that Model. I have a PR on the way (maybe today, maybe later this week) that will simplify the interaction between View-models and the Models, so it probably worth waiting until that lands before proceeding. I'll check in here when it has.

@danielballan
Copy link
Member

danielballan commented Jan 27, 2021

The work I referred to in my previous comment is now merged from #97. This will need to be rebased on master to absorb those changes, but fortunately it should require only a minor adjustment to what you have done so far.

Next steps:

  • Add a ParasiteAxes model in bluesky_widgets.model.plot_specs inheriting from Axes and extending it with the concept of a host and sense of which axis it is sharing --- x, y, or both (if that's allowed?)
  • When the view receives a bluesky_widgets.model.plot_specs.Axes model it should make normal matplotlib.axes.Axes. When it receives a bluesky_widgets.model.plot_specs.ParasiteAxes model it should make matplotlib...[blah blah blah].ParasiteAxes.
  • Work with example data from LIX as a real test case for plotting a scan with one detector (y) over two motors (sharing x). I have some, just need to find it and pack it up for you.

@danielballan
Copy link
Member

P.S. I am happy to do a call to check in on this if it would be helpful, though this week is 🍌 🍌 🍌 so it would be best to plan for next week.

@bsobhani
Copy link
Contributor Author

Yes I think it would be good to discuss over a call - next week works for me too. In the meantime I will look into the next steps you suggested.

@@ -129,12 +189,17 @@ def _on_image_added(self, event):
image_spec = event.item
self._add_image(image_spec)

def axes_plot(self, x, y, label, *args, **kwargs):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make this private for now? We want to over-ride it internally but maybe not commit to making it public API yet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and if you are going to take in *args make sure you use them

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by make it private?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prepend _ to the method name to signal that downstream code shouldn't call it (directly). It's still possible for downstream code to use it, of course, but it signals that they shouldn't and that if they do, we reserve the right to make changes that could break their code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I understand.

@danielballan
Copy link
Member

Path forward here is:

  • Rebase
  • Get the model side ParasiteAxes and HostAxes solid.
  • Rework the view side on that.

@bsobhani
Copy link
Contributor Author

What I understand is that instead of 1 parasite per Artist (this is what I currently have), we are doing 1 parasite per Axes.

If a plot is to have multiple axes, I would think that you would do this by creating multiple Lines objects, and then giving the Figure constructor these axes, like this:

fig_model = Figure([lines1.axes, lines2.axes], title="asdf")

The problem is that a Lines object also creates its own figure, so when I run the above I get an error saying Figures may only be set once.

So my question is, how do you draw multiple lines on different Axes, on the same figure?

@danielballan
Copy link
Member

Good question. Answer:

from bluesky_widgets.models.plot_specs import Axes

axes = Axes()
figure = Figure([axes], title="...")
line1 = Lines(..., axes=axes)
line2 = Lines(..., axes=axes)

Does that address the question?

@bsobhani
Copy link
Contributor Author

Yes it does, thanks.

@bsobhani
Copy link
Contributor Author

bsobhani commented Mar 17, 2021

The way the colors work for non-parasite plotting is that there is a color for each scan. Should I keep this behavior for parasite plotting and make it so that each line within a scan corresponds to a different line style?

@danielballan
Copy link
Member

Oops, somehow I missed the notification of your comment 12 days ago, @bsobhani. Thanks for your patience with my slow reply.

I don’t understand the question yet. To take the LIX use case as an example, if I do a scan of one detector moving two motors, I’d have two x axes (one of them being a “parasite”) and one line. To take a different example, if I have one detector scanned against one motor that I was to display against two y axes—say, Celsius and Fahrenheit—I’d still have two lines. In what scenario do we get two lines representing the same scan?

@bsobhani
Copy link
Contributor Author

bsobhani commented Apr 1, 2021

No problem @danielballan.

I think what you describe is that is probably the most useful application of this.

The example I had in mind is if you want to compare two sensors that measure the same thing but in different units. At ESM for example they have measured beam intensity in two different ways: one way using gold foil and another way using their electron analyser. One is measured in amps but the other in counts but it may still be useful to view both measurements in one plot if for example you want to compare their performance.

It might be rare that someone would want to use this though so maybe it is better to keep it simple for now. Over the next few days I will test how what I have now works and also make a few other changes that were mentioned.

@danielballan
Copy link
Member

Oh, that’s a great use case to include. Thanks for explaining.

Then to answer your original question

The way the colors work for non-parasite plotting is that there is a color for each scan. Should I keep this behavior for parasite plotting and make it so that each line within a scan corresponds to a different line style?

I would say yes. I imagine they would need to have separate entries in the plot legend and be visually distinguishable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants