karolzak / ipyplot

IPyPlot is a small python package offering fast and efficient plotting of images inside Python Notebooks. It's using IPython with HTML for faster, richer and more interactive way of displaying big numbers of images.
MIT License
415 stars 41 forks source link

Cannot display images from a full Windows path #17

Closed eafpres closed 2 years ago

eafpres commented 4 years ago

Running in Windows 10 Jupyter in Chrome, launched from miniconda prompt Code is in c:/eaf llc/aa-analytics and bi/ipyplot and that is where Jupyter is launched from There is a subdirectory "samples" in the code directory, which contains images

If I specify the path like:

images = \
['c:/eaf llc/aa-analytics and bi/ipyplot/samples/cosine_loss.jpg',
 'c:/eaf llc/aa-analytics and bi/ipyplot/samples/crane_w_bucket.jpg',
 'c:/eaf llc/aa-analytics and bi/ipyplot/samples/CRISP-DM on Trello Example.jpg',
 'c:/eaf llc/aa-analytics and bi/ipyplot/samples/gans_for_good.jpg',
 'c:/eaf llc/aa-analytics and bi/ipyplot/samples/learned_optimizer.jpg',
 'c:/eaf llc/aa-analytics and bi/ipyplot/samples/LTC_half_cheetah_model.jpg',
 'c:/eaf llc/aa-analytics and bi/ipyplot/samples/MSI_algorithm.jpg',
 'c:/eaf llc/aa-analytics and bi/ipyplot/samples/neuroadaptation.jpg',
 'c:/eaf llc/aa-analytics and bi/ipyplot/samples/parametric_UMAP.jpg']

The images are not found by iplyplot

If I use:

images = \
['samples/cosine_loss.jpg',
 'samples/crane_w_bucket.jpg',
 'samples/CRISP-DM on Trello Example.jpg',
 'samples/gans_for_good.jpg',
 'samples/learned_optimizer.jpg',
 'samples/LTC_half_cheetah_model.jpg',
 'samples/MSI_algorithm.jpg',
 'samples/neuroadaptation.jpg',
 'samples/parametric_UMAP.jpg']

it works fine

karolzak commented 4 years ago

Hi @eafpres Good catch, thanks for reporting that. I've run some tests and investigated this a bit and it seems it's related to the fact that the browser cannot access users file system directly so absolute path like c:/your/path/img1.jpg will not work at all. Each absolute path should be converted to a relative path as you did in your example.
Another thing I realized is that starting a jupyter server starts some sort of web server which can access files stored on the same level as the jupyter server or below that level. Any files above the level of where jupyter server is running won't be accessible. So following your example: If you're running your jupyter server from c:/eaf llc/aa-analytics and bi/ipyplot directory you won't be able to access images located under c:/eaf llc/aa-analytics and bi directory.

3 action items I see here to fix/improve this:

eafpres commented 4 years ago

3 action items I see here to fix/improve this:

  • add info about relative vs absolute paths to the docs
  • add warning about jupyter web server start location and potential issues in displaying images from inaccessible directories
  • add os.path.relpath(..) to automatically convert all the absolute paths into relative paths in the internal function responsible for generating HTML img elements

Thanks for this--I had first noticed that it could not access a level above, then proved it was general to specifying an absolute path. I guess those are actually slightly different. I think adding to the docs is a great first step, to avoid others doing what I did!

Thank you again for this; once I figured out the path, it's really simple and it's cool you included the automatic breakout of classes by folder.

eafpres commented 4 years ago

I confirm the following works if Jupyter is launched from the level of the images or above, with the code somewhere below that:

image_path = 'c:/eaf llc/aa-analytics and bi'
path = os.getcwd()
rel_path = os.path.relpath(image_path, path)
files = os.listdir(rel_path)
images = [rel_path + '\\' +
          files[i] for i in range(len(files)) 
          if re.search(".jp", files[i]) is not None]
karolzak commented 4 years ago

Thanks for double checking and confirming that! You can achieve the same thing with a 2-liner as below using glob package:

import glob
import os

abs_paths = glob.glob('c:/eaf llc/aa-analytics and bi/*.jp*')
relative_paths= [os.path.relpath(path) for path in abs_paths]