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

refactoring the plotting system #166

Merged
merged 49 commits into from
Jun 4, 2021

Conversation

wpfff
Copy link
Contributor

@wpfff wpfff commented Dec 3, 2020

some first working bits and pieces for slightly restructured plotting code.
main aspects:

  • separate all parts that are not backend (like matplotlib) dependent but more general. This includes quite a lot of the current logic in the autoplot elements.
  • should end up such that adding other plotting backends should be fairly easy.

Some notes for orientation:

  • there's no more mpl.py file but rather a submodule
  • included a simple way for customizing matplotlib appearance using a config system with plottrconfig_*.py file
  • added a new class 'AutoFigureMaker' whose job is only to track the elements of the figure and arrange them into subplots depending on user settings.
  • 2d plots are not yet working, but it should be enough to get an idea of where it's going.

@wpfff wpfff requested a review from jenshnielsen December 3, 2020 02:32
@wpfff
Copy link
Contributor Author

wpfff commented Dec 3, 2020

@jenshnielsen
this is still very rough, but i thought i'll open a PR already to give you chance to look since you also wanted to make changes to the matplotlib parts.

some tests are working fine, which hopefully should be enough to get an idea, see:
/test/gui/mpl_autoplot.py
/test/apps/autoplot_app.py

(2D plots i need to plug back in -- i stopped today when the main parts seemed to fit together)

would be great to hear any thoughts!

@wpfff
Copy link
Contributor Author

wpfff commented Dec 3, 2020

i should also add that the recent changes for high-dpi scaling aren't yet re-implemented here. but shouldn't be too hard to get that merged back in.

if len(plotItem.data) == 2:
style = 'line'
elif len(plotItem.data) == 3:
style = 'image'
Copy link
Collaborator

Choose a reason for hiding this comment

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

what's the difference between this "style" and "PlotType" enum? also, shouldn't determinePlotDataType be used here somehwere?

Copy link
Collaborator

Choose a reason for hiding this comment

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

As I understand it style is basically:

1D or 2D

PlotDataType and PlotType are further refinements of this.

Perhaps we should consider if we can streamline these types. My understanding is basically that we can categorize the data as follows. I like to think of it as a mapping from data types to valid plot types

  • 1d data ordered: [1D line plot, 1D points plot (scatter)]
  • 1d data not ordered: [1D points plot (scatter)]
  • 2d data on equidistant grid: [image, colormesh, scatter2d]
  • 2d data on non equidistant grid: [colormesh, scatter2d]
  • 2d data no structure: [scatter2d]

Further to that there is choice between single and multitrace 1d plots which seems to be somewhat unrelated.

it seems to me that these types currently mix things that should be separate concerns but since that code is the same as it was before in mpl.py we should probably not touch that in this pr

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good point, Mikhail. this could essentially be the same thing. the idea is that any backend could essentially support different types of plots that for instance also the user may want to implement (i'm thinking of a few custom plots that would be useful for specific measurements). Other backends might support 3D graphics in a decent way. etc...

Jens, agreed. The only thing i'd want to make sure of is that adding plot types should be somewhat easy, and potentially doable through a plugin rather than only by modifying 'core' code.

I'm definitely open to come up with a structure that does things 'right' in this effort, in terms of separation. There's no immediate rush with merging this into the main branch.

"""Set the matplotlib style based on available config files."""
styleFiles = configFiles('plottr_default.mplstyle')
if len(styleFiles) > 0:
plt.style.use(styleFiles[0])
Copy link
Collaborator

Choose a reason for hiding this comment

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

if there are more the one files, then perhaps they should be applied in a "hierarchical sum" like, say, git config files?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, that'd be great. i have to mess around with rc params in matplotlib a bit to see how that could work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So far I don't see an easy way with the matplot methods directly.
I'm thinking of including this into a central config file for plottr that will also configure matplotlib parameters.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i pushed a proposal for a config system with just python files (so no other specific file format) that both supports the hierarchical sum concept you mentioned, and can do all configuration of matplotlib.

Copy link
Collaborator

@jenshnielsen jenshnielsen left a comment

Choose a reason for hiding this comment

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

@wpfff I think this looks promising. There is a bit of work to ensure feature parity with the existing code and some cleanup but I like the general direction

if len(plotItem.data) == 2:
style = 'line'
elif len(plotItem.data) == 3:
style = 'image'
Copy link
Collaborator

Choose a reason for hiding this comment

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

As I understand it style is basically:

1D or 2D

PlotDataType and PlotType are further refinements of this.

Perhaps we should consider if we can streamline these types. My understanding is basically that we can categorize the data as follows. I like to think of it as a mapping from data types to valid plot types

  • 1d data ordered: [1D line plot, 1D points plot (scatter)]
  • 1d data not ordered: [1D points plot (scatter)]
  • 2d data on equidistant grid: [image, colormesh, scatter2d]
  • 2d data on non equidistant grid: [colormesh, scatter2d]
  • 2d data no structure: [scatter2d]

Further to that there is choice between single and multitrace 1d plots which seems to be somewhat unrelated.

it seems to me that these types currently mix things that should be separate concerns but since that code is the same as it was before in mpl.py we should probably not touch that in this pr

@wpfff
Copy link
Contributor Author

wpfff commented Dec 4, 2020

Thanks for the feedback, both of you! I'll probably have some time this weekend to ponder some of the deeper suggestions and see if i can refine the concept a bit (especially the role of the PlotType, style, etc.).

wpfff added 9 commits January 3, 2021 10:41
# Conflicts:
#	plottr/__init__.py
#	plottr/plot/mpl.py
- PlotType is not a global concept, but something only the MPL plot uses
- PlotItem.style is replaced with type PlotDataType to streamline
- make no assumptions about plotting, leave all details to the backend classes
- PlotWidgets obtain data from the Nodes, and process UI options
- based on UI options, data is processed and passed to FigureMaker
- No actual plotting happens in the Widget, this is the role of the FigureMaker
deleted old templates.
wpfff added 3 commits April 30, 2021 08:48
- switch to configuration method that allows hierarchical resolution of user configuration (pure python, because that seems the best solution for configuring matplotlib)
@wpfff wpfff requested a review from FarBo May 3, 2021 12:32
@FarBo
Copy link
Collaborator

FarBo commented May 3, 2021

@wpfff
I see copy metadata is added. Legend seems behaving fine.
Still the plottype buttons are very small compared to the latest release:
https://1drv.ms/u/s!AkKmOu47nt6ygrI_W8T8SJUw_AHZFQ?e=ArafkO

@wpfff
Copy link
Contributor Author

wpfff commented May 3, 2021

Still the plottype buttons are very small compared to the latest release:
https://1drv.ms/u/s!AkKmOu47nt6ygrI_W8T8SJUw_AHZFQ?e=ArafkO

@FarBo : true -- matter of preference I guess. Along with one of my recent commits I made them the same size as the ones in the other toolbar to be consistent which i thought looked better (they are dpi-scaled, though).
I'm open to changing that back, though, if you disagree.

@FarBo
Copy link
Collaborator

FarBo commented May 3, 2021

@wpfff
true -- matter of preference I guess. Along with one of my recent commits I made them the same size as the ones in the other toolbar to be consistent which i thought looked better (they are dpi-scaled, though). I'm open to changing that back, though, if you disagree.

The buttons on the right looks natural to me and as far as I remember, small sizes (left) are not preferred by some of users.
I think it would be nice to have the bigger like the right plot.

@FarBo
Copy link
Collaborator

FarBo commented May 11, 2021

@wpfff
Thanks for the updates. I didn't go through the code structure and only tested the functionality. These final commits solved all my raised concerns. :)

@wpfff
Copy link
Contributor Author

wpfff commented May 12, 2021

@wpfff
Thanks for the updates. I didn't go through the code structure and only tested the functionality. These final commits solved all my raised concerns. :)

Thanks, @FarBo! I'm still waiting for comments from @astafan8 (for this PR i think it'd be important that there's some consensus on structure, and he wanted to have a look)

@wpfff
Copy link
Contributor Author

wpfff commented May 22, 2021

@astafan8 - just to poke you :) are you still planning on giving comments on this?
If not, i'd like to merge soon. It's quite well-behaved now and i'm working on an additional backend that follows this structure.
There will probably still be some refactoring once i have another backend going (mainly regarding what should be part of the matplotlib specific part and what is more general) but the overall structure works well i think.

@astafan8
Copy link
Collaborator

just to poke you :) are you still planning on giving comments on this?

thanks @wpfff ! I will do this week

@astafan8
Copy link
Collaborator

@wpfff ETA today :)

Copy link
Collaborator

@astafan8 astafan8 left a comment

Choose a reason for hiding this comment

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

left a few notes/comments but let's merge this finally :) i'm happy to tag a release tomorrow

assert len(plotItem.data) == 2
lbl = plotItem.labels[-1] if isinstance(plotItem.labels, list) and len(plotItem.labels) > 0 else ''
x, y = plotItem.data
return axes[0].plot(x, y.real, label=lbl, **plotItem.plotOptions)
Copy link
Collaborator

Choose a reason for hiding this comment

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

what is .real really needed for? isn't the data already split into real/imag/mag/phase parts? same in the plotImage method

Suggested change
return axes[0].plot(x, y.real, label=lbl, **plotItem.plotOptions)
return axes[0].plot(x, y, label=lbl, **plotItem.plotOptions)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good point -- this looks wrong (although there was still a -- hidden -- possibility that data might be complex typed).
i fixed it in the correct spot (apparently numpy.ma.abs can produce complex valued data).

@astafan8 astafan8 removed the request for review from jenshnielsen June 1, 2021 15:20
@wpfff
Copy link
Contributor Author

wpfff commented Jun 1, 2021

Thanks, @astafan8 -- i'll adopt your suggestions today.
I'll probably also include the importlib suggestion. Much better solution -- i just hadn't looked properly :)

@wpfff wpfff merged commit e648047 into toolsforexperiments:master Jun 4, 2021
@wpfff wpfff deleted the betterplotting branch June 4, 2021 03:04
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.

4 participants