-
Notifications
You must be signed in to change notification settings - Fork 32
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
Allow borrowing plot points by adding PlotPoints::Borrowed
#35
base: main
Are you sure you want to change the base?
Conversation
self, | ||
ui: &mut Ui, | ||
build_fn: impl FnOnce(&mut PlotUi) -> R + 'a, | ||
build_fn: impl FnOnce(&mut PlotUi<'b>) -> R + 'a, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a tricky one.
The following example helped me with figuring out the correct lifetime annotation:
trait PlotItem: std::fmt::Debug {}
#[derive(Debug)]
struct Line<'a>(&'a [f64]);
impl<'a> PlotItem for Line<'a> {}
#[derive(Debug)]
struct PlotUi<'a>(Vec<Box<dyn PlotItem + 'a>>);
impl<'a> PlotUi<'a> {
fn line(&mut self, line: Line<'a>) {
self.0.push(Box::new(line));
}
}
fn show<'a>(f: impl FnOnce(&mut PlotUi<'a>)) {
let mut foo = PlotUi(Vec::new());
f(&mut foo);
}
fn main() {
let v = vec![1.0, 2.0];
show(|plot_ui| {
plot_ui.line(Line(&v));
println!("{plot_ui:?}");
});
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like we should add that code as an example or test then 🤔
Thank you for your work! I am working on a plot viewer that has to render a lot of points and this seems like one of the things that might improve its performance. Currently plotting 30000 points or so seems to bring the FPS down to 30 with just one plot. Looking forward to this pull request being merged! |
@riccardostokker Could you please try this branch in your project to see the performance benefit? You can do so by replacing egui_plot = { git = "https://github.com/mo8it/egui_plot.git", branch = "borrow", version = "0.28.1" } |
I just pushed a commit to relax the closure requirements of |
I am currently using a custom struct that stores the points that should be printed in the plot. This makes generating the vector of This is how I am currently drawing my plots: for (circuit, waveform) in mappings {
let points: Vec<[f64; 2]> = waveform
.x
.iter()
.zip(waveform.y.iter())
.map(|(&x, &y)| [x, y])
.collect();
let points = PlotPoints::new(points);
let line = Line::new(points).name(circuit.label.clone());
lines.push(line);
} |
Why don't you merge the two fields |
The |
Then we need a more flexible generator which takes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
self, | ||
ui: &mut Ui, | ||
build_fn: impl FnOnce(&mut PlotUi) -> R + 'a, | ||
build_fn: impl FnOnce(&mut PlotUi<'b>) -> R + 'a, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like we should add that code as an example or test then 🤔
/// | ||
/// These can be an owned `Vec` or generated with a function. | ||
pub enum PlotPoints { | ||
pub enum PlotPoints<'a> { | ||
Owned(Vec<PlotPoint>), | ||
Generator(ExplicitGenerator), | ||
// Borrowed(&[PlotPoint]), // TODO(EmbersArc): Lifetimes are tricky in this case. | ||
Generator(ExplicitGenerator<'a>), | ||
Borrowed(&'a [PlotPoint]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should update this docstring
@mo8it looks good - could you fix the changes emilk requested? |
Done the following TODO:
egui_plot/egui_plot/src/items/values.rs
Line 160 in d00fa85
It is really an inner pain for me to clone a long
Vec
every time just to plot it.Breaking changes
The addition of lifetimes can be a breaking change that should be communicated in the CHANGELOG.
Demo
I tested it using the following small demo:
Please tell me where I should add a test and how you prefer it.