Before somebody marks this question as a duplicate, I should mention that I'm not using Plotly Dash
or a Jupyter Notebook
which were what all of the other SO answers I could find were pertaining to.
Using regular Plotly and a regular Python script from a terminal, in Ubuntu 20.04, when I run a script, for example this:
import numpy as np
import plotly.graph_objects as PlotlyGraphObjects
SHOW_PLOTLY_MOUSEOVERS = False
def main():
lidar_points = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]], dtype=np.float32)
print('\n' + 'lidar_points.shape')
print(lidar_points.shape)
s3dPoints = PlotlyGraphObjects.Scatter3d(x=lidar_points[0], y=lidar_points[1], z=lidar_points[2], mode='markers', marker={'size': 1})
plotlyFig = PlotlyGraphObjects.Figure(data=[s3dPoints])
plotlyFig.update_layout(scene_aspectmode='data')
if not SHOW_PLOTLY_MOUSEOVERS:
plotlyFig.update_layout(hovermode=False)
plotlyFig.update_layout(scene=dict(xaxis_showspikes=False,
yaxis_showspikes=False,
zaxis_showspikes=False))
# end if
plotlyFig.show()
# end function
if __name__ == '__main__':
main()
Plotly opens a new tab in Chrome (my default browser) and shows the data:
In this particular example Plotly choose port 43001, presumably because it determined that port was available. Is there a way I can set which port Plotly uses, or at least force it to use the same port each time?
The reason I'm asking is I have to use Plotly code inside a Docker container and if I can force Plotly to use a certain port then I can open that port to the host when starting the container, but since I don't currently know how to force Plotly to use a certain port I'm unable to see the rendering. I checked the documentation for Plotly show
https://plotly.com/python/renderers/ and surprisingly did not find anything pertaining to setting the port.
Delving into the plotly codes, I found that the server's port is set to '0', which is going to be translated to a random available number.
As the '0' is hard coded, you need to overwrite the entire function that opens browser. Run this script, e.g., in a start-up script.
import webbrowser
import plotly
from plotly.io._base_renderers import BaseHTTPRequestHandler, HTTPServer
def open_html_in_browser(html, using=None, new=0, autoraise=True):
"""
Display html in a web browser without creating a temp file.
Instantiates a trivial http server and uses the webbrowser module to
open a URL to retrieve html from that server.
Parameters
----------
html: str
HTML string to display
using, new, autoraise:
See docstrings in webbrowser.get and webbrowser.open
"""
if isinstance(html, str):
html = html.encode("utf8")
browser = None
if using is None:
browser = webbrowser.get(None)
else:
if not isinstance(using, tuple):
using = (using,)
for browser_key in using:
try:
browser = webbrowser.get(browser_key)
if browser is not None:
break
except webbrowser.Error:
pass
if browser is None:
raise ValueError("Can't locate a browser with key in " + str(using))
class OneShotRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
bufferSize = 1024 * 1024
for i in range(0, len(html), bufferSize):
self.wfile.write(html[i : i + bufferSize])
def log_message(self, format, *args):
# Silence stderr logging
pass
server = HTTPServer(("127.0.0.1", 54321), OneShotRequestHandler) # fixed port number
browser.open(
"http://127.0.0.1:%s" % server.server_port, new=new, autoraise=autoraise
)
server.handle_request()
# overwrite the original implementation
plotly.io._base_renderers.open_html_in_browser = open_html_in_browser