Plot `show` Method Not Working on Windows 10
M-NK-Y opened this issue · comments
MWE is given from excerpt within plot.rs
:
use plotly::common::Mode;
use plotly::{Layout, Plot, Scatter};
fn line_and_scatter_plot() {
let trace1 = Scatter::new(vec![1, 2, 3, 4], vec![10, 15, 13, 17])
.name("trace1")
.mode(Mode::Markers);
let trace2 = Scatter::new(vec![2, 3, 4, 5], vec![16, 5, 11, 9])
.name("trace2")
.mode(Mode::Lines);
let trace3 = Scatter::new(vec![1, 2, 3, 4], vec![12, 9, 15, 12])
.name("trace3");
let mut plot = Plot::new();
plot.add_trace(trace1);
plot.add_trace(trace2);
plot.add_trace(trace3);
let layout = Layout::new().title("<b>Line and Scatter Plot</b>".into());
plot.set_layout(layout);
# if false { // We don't actually want to try and display the plot in a browser when running a doctest.
plot.show();
# }
}
fn main() -> std::io::Result<()> {
line_and_scatter_plot();
Ok(())
}
Expected: Generated HTML to be opened using the user's default browser.
Actual: System exits with code 0, though no process is spawned/made apparent.
At a glance the issue here seems to be with the parameters used when attempting to open the browser and more specifically their formatting (possibly a quirk of using the older syntax affected by the now closed issue #29494 or alternatively, regarding how the output
method is being handled on Windows).
As an aside I'd imagine this probably went undetected for some time courtesy of:
"// We don't actually want to try and display the plot in a browser when running a doctest."
but this is just speculation and fortunately this can be hastily remedied and I'll open a PR for shortly.
Thanks! ❤️
Just thought I'd leave an addendum here, I think there could be some kind of versioning issue because per #131 this should be fixed but unfortunately this appears to still be an issue as of version 0.8.4
.
Edit: Updated description within PR, but may be duplicate of #129 if updated args
syntax isn't desirable.
Confirmed not working on Windows 11 as well.
I have the same problem.
https://github.com/igiagkiozis/plotly/blob/8903ff03ce9e8183624c40ccf7ddf863799cb92e/plotly/src/plot.rs#L274
I didn't try this out here, but in my own project and using explorer.exe
instead of cmd.exe
works for me.
So
#[cfg(target_os = "windows")]
fn show_with_default_app(temp_path: &str) {
use std::process::Command;
Command::new("explorer")
.arg(temp_path)
.output()
.expect(DEFAULT_HTML_APP_NOT_FOUND);
}
should technically work?
edit: Oh, just noticed the PR - if #133 works fine, then that's great!
@mfreeborn just tried it out and the plot is opened without any problems in the browser on Windows 11 :D
Don’t work out the box on my Windows 11. Seems like a problem with temp files, if I supply my own html file, it works fine. I use this workaround for now.
Windows 11 23H2
Since show_html
has been added in in v0.9.1 with #217 I've tested out some things again.
Seems like the current Windows implementation for Plot::show_with_default_app
is not working with ampersands &
in the filename
Minimal example to demonstrate error:
fn main() {
let plot = plotly::Plot::new();
plot.show_html("te&st.html");
}
(on a Windows machine)
Returns a
The system cannot find the file te.
'st.html' is not recognized as an internal or external command,
operable program or batch file.
The current implementation
Lines 485 to 492 in 7bfae55
uses
cmd /C start '.\te&st.html'
which for some reason not known to me interprets the
&
in the filename as the separator between current and next command
Using explorer '.\te&st.html'
instead works (like mentioned in #132 (comment))
It's technically a different issue to this one, but kinda adjacent imo
Should I just open another issue or leave it in this?
This seems to be a Windows specific parsing problem, not a plotly
problem. For cmd.exe
, the &
symbols seems to mean chaning of commands. Based on this superuser answer this has to do with how Windows API parses the arguments for cmd.exe
. More info as linked in that answer can be found here.
@fsktom, I have no way of testing on Windows. Could you try the suggestion in that answer, prepending the path with \\?\
and see if that works.
Yeah, it's most definitely a Windows issue, just wanted to mention it here since it will occur if you use a file path with an ampersand on Windows. We could just say to not use &
in the filename in the function docs, but I think it should work since it's not a forbidden Windows filename symbol.
@andrei-ng thanks for doing this bit of research, I've tried it out and... it's weird (like everything with Windows...).
Command I used: cmd /C start "" "\\?\Q:\plotlyerr\te&st.html"
- The provided solution seems to only work with absolute paths (bad)
- It seems to only work when you execute it directly in the Windows command prompt
i. not in PowerShell (which I think is the default prompt in newer Windows versions, though I'm not sure)
ii. more relevant: not when you put in the code :))
Executing this command in PowerShell or via std::process::Command
still parses the &
as a chain of commands.
Which shouldn't surprise me since it states in the docs that the prefix won't always work heh
Many but not all file I/O APIs support "\?"; you should look at the reference topic for each API to be sure.
Changing cmd
to explorer
works for my use case
#[cfg(target_os = "windows")]
fn show_with_default_app(temp_path: &str) {
use std::process::Command;
Command::new("explorer")
.arg(temp_path)
.spawn()
.expect(DEFAULT_HTML_APP_NOT_FOUND);
}
Thanks for looking into it further. I hoped that there was a quick workardound somehow. But indeed ... Windows ... nothing is simple.
I think we should keep all the discussion here and not open a new issue (to reply to a previous comment of yours). They are not one and the same issue, but kind of related.