33
$\begingroup$

I want to have in Mathematica the same result I have in Python: enter image description here

I have this nice effect simply by using very thin lines. But it seems in Mathematica thickness property has some limit and i just got this:

xy = RandomReal[1, {10000, 2}];
ListLinePlot[xy, PlotStyle -> Thickness@10^-5]

enter image description here

Playing with opacity doesn't help. I can't figure out how to reproduce this effect..

$\endgroup$
9
  • 2
    $\begingroup$ python has no built in plot. you ought to specify what module you are using $\endgroup$
    – george2079
    Commented Nov 21, 2014 at 12:31
  • 3
    $\begingroup$ It's matplotlib $\endgroup$
    – funnyp0ny
    Commented Nov 21, 2014 at 12:55
  • 1
    $\begingroup$ Nice pict. It can be used as wallpaper to simulate an erased blackboard. $\endgroup$
    – Sigur
    Commented Nov 21, 2014 at 18:40
  • 2
    $\begingroup$ @AlexeyPopkov Win7 (IPython notebook from last python xy). $\endgroup$
    – funnyp0ny
    Commented Nov 21, 2014 at 22:21
  • 1
    $\begingroup$ @BioGeek actually this is full code in IPython. In contrast with ordibary python.exe it automatically imports many libraries like numpy and matplotlib. If you want to do it manually - you need numpy and matplotlib. Then just add these 2 lines in the beginning: from numpy import random; from matplotlib.pyplot import plot, show and add this in the end: show(). It should work $\endgroup$
    – funnyp0ny
    Commented Dec 16, 2014 at 12:00

4 Answers 4

31
$\begingroup$

Your comment raises interesting question:

I got everything simply faded and flat, while in the example - its all bright and sharp

I think the problem is related to the fact that Mathematica's graphical functions always work in linear colorspace. Starting from Pickett's solution with better resampling method, in version 10.0.1 we obtain:

$HistoryLength = 0;
xy = RandomReal[1, {10000, 2}];
img = ImageResize[
  Rasterize[
   ListLinePlot[xy, ImageSize -> 10000, 
    PlotStyle -> Directive[AbsoluteThickness[1],(*Opacity[.5],*)Blue]], "Image"], 
  300, Resampling -> {"Lanczos", 30}]

img

This image is obtained in the linear RGB colorspace while our monitors work in the sRGB colorspace. The problem is discussed in some details in this question of mine. We may apply a gamma correction as a quick-and-dirty way to fix this:

img2 = ImageApply[#^1.3 &, img]

img2

Still far from ideal. Playing with Resampling and using more correct method of converting the linear RGB into sRGB can help to produce better colors.


UPDATE: A detailed analysis

I have found that Resampling methods "Constant" and "Linear" better reproduce the Python's result. Increasing the ImageSize (i.e. decreasing the actual thickness of the lines) also helps (but the memory required for the rasterization grows as the square of ImageSize!):

$HistoryLength = 1;
xy = RandomReal[1, {10000, 2}];
img = ImageResize[
  Rasterize[
   Style[ListLinePlot[xy, ImageSize -> 15000, AspectRatio -> 224/336, 
     PlotStyle -> Directive[AbsoluteThickness[1], Blue], 
     Axes -> False, PlotRangePadding -> 0], Antialiasing -> False], 
   "Image"], 336, Resampling -> "Constant"]

img

Rescaling color intensities to run from 0 to 1 significantly improves the appearance:

img = Image[Rescale[ImageData[img]]]

img

Compare with the Python's result:

origImgCrop = 
 ImageTake[
  Import["https://i.sstatic.net/ycM0u.png"], {97, 310}, {42, 367}]

Python's image

The difference is still noticeable. One possible reason is insufficient ImageSize but I cannot check this directly because ImageSize larger than 15000 will kill my system with 8 Gb of physical memory. Let us crop the img too and compare the horizontal lightness distributions in the images:

imgCrop = ImageTake[img, {6, -6}, {6, -6}]

imgCrop

imgCrop // ImageDimensions
origImgCrop // ImageDimensions
{326, 214}
{326, 214}

Mean horizontal lightness distributions for Python's (blue points) and Mathematica's (orange points) outputs can be computed by taking the intensity values of the first RGB channel (the Red channel) because the first and the second channels contain identical values and actually describe the lightness:

origHorSum = 
  Total[#]/Length[#] &@
   ImageData[origImgCrop, Interleaving -> True][[;; , ;; , 1]];
horSum = Total[#]/Length[#] &@
   ImageData[imgCrop, Interleaving -> True][[;; , ;; , 1]];

ListPlot[{origHorSum, horSum}, Frame -> True, PlotRange -> {0, 1}]

plot

Let us see how this plot changes if we set ImageSize to 10000:

plot for ImageSize->10000

The same for ImageSize -> 8000:

plot for ImageSize->8000

From these comparisons I conclude that we cannot reproduce the Python's appearance just by increasing ImageSize.

And finally, let us look at the "natural" appearance of the image obtained with ImageSize->15000 by converting it into the sRGB colorspace (the function linear2srgb is implemented by Jari Paljakka and can be found in this answer):

ImageApply[linear2srgb, imgCrop]

sRGB image obtained with ImageSize->15000


UPDATE 2: simulating an erased blackboard

In the comments Sigur expressed the idea that this type of plot simulates an erased blackboard and can be used as a background for slides. In PowerPoint 2003 (which I currently use) slides by default have size 25.4x19.05 cm with AspectRatio -> 1905/2540. For obtaining a 1680 pixels wide background images the above code can be modified as follows:

$HistoryLength = 0;
xy = RandomReal[1, {10000, 2}];
img = ImageResize[
  Rasterize[
   Style[ListLinePlot[xy, ImageSize -> 15000, 
     AspectRatio -> 1905/2540, 
     PlotStyle -> Directive[AbsoluteThickness[1], Black], 
     Axes -> False, PlotRangePadding -> 0], Antialiasing -> False], 
   "Image"], 1680, Resampling -> "Constant"];
img = Image[Rescale[ImageData[img]]]
Export["erased blackboard.png", img]
img2 = ImageApply[linear2srgb, img]
Export["erased blackboard (sRGB).png", img2]

Optimized PNG files can be downloaded here: "erased blackboard.png", "erased blackboard (sRGB).png".


UPDATE 3: more about the erased blackboard

It seems that inverting the colors and blurring produces an image that feels more like true erased blackboard. With blur we need not lossless PNG anymore and can use lossy JPG compression to reduce the file size. Here is a way to do everything in Mathematica (images are clickable!):

$HistoryLength = 0;
xy = RandomReal[1, {10000, 2}];
img = ImageResize[
   Rasterize[
    Style[ListLinePlot[xy, ImageSize -> 15000, 
      AspectRatio -> 1905/2540, 
      PlotStyle -> Directive[AbsoluteThickness[1], White], 
      Axes -> False, PlotRangePadding -> 0, Background -> Black], 
     Antialiasing -> False], "Image"], 1680, Resampling -> "Constant"];
imgBlur = Blur[Image[Rescale[ImageData[img]]], 3]
Export["erased blackboard blurred.jpg", imgBlur]

erased blackboard blurred.jpg

linear2srgb = 
 Compile[{{Clinear, _Real, 1}}, 
  With[{\[Alpha] = 0.055}, 
   Table[Piecewise[{{12.92*C, 
       C <= 0.0031308}, {(1 + \[Alpha])*C^(1/2.4) - \[Alpha], 
       C > 0.0031308}}], {C, Clinear}]], 
  RuntimeAttributes -> {Listable}]; imgBlur2 = 
 ImageApply[linear2srgb, imgBlur]
Export["erased blackboard blurred (sRGB).jpg", imgBlur2]

erased blackboard blurred (sRGB).jpg

$\endgroup$
19
  • 1
    $\begingroup$ @Sigur With my code you get a 336x224 pixels raster images. In principle you can just take an image from my answer and use ColorConvert for obtaining a grayscale version of it. Use Binarize for obtaining a black&white version. But probably 336x224 pixels size is insufficient for your purposes. $\endgroup$ Commented Nov 22, 2014 at 17:26
  • 1
    $\begingroup$ @Sigur I added the "UPDATE 2" section in my answer dedicated to your idea. $\endgroup$ Commented Nov 22, 2014 at 23:43
  • 2
    $\begingroup$ @AlexeyPopkov after some processing your image looks even cooler: i.imgur.com/1p5sEDr.jpg $\endgroup$
    – funnyp0ny
    Commented Nov 23, 2014 at 20:04
  • 1
    $\begingroup$ @funnypony Now it is true blackboard! BTW, I notice that your image is blurred probably due to lossy conversion to JPG automatically applied by imgur.com (or you have made it intentionally?). I am not sure whether blurred version is better or worse as a background for slides. What do you think? $\endgroup$ Commented Nov 23, 2014 at 21:30
  • 1
    $\begingroup$ @AlexeyPopkov well blurring, sepia and vignette are just most common and straightforward effects one can apply to get a new feeling of an image. generally no particular idea) $\endgroup$
    – funnyp0ny
    Commented Nov 23, 2014 at 21:53
18
$\begingroup$

On-screen, lines are always at least 1 pixel wide in Mathematica, regardless of the thickness setting. Not sure what you tried with Opacity, as it seems to be possible to achieve the same effect:

PlotStyle -> Directive[AbsoluteThickness[1], Opacity[.05]]

Mathematica graphics

$\endgroup$
0
10
$\begingroup$

You tried to decrease the width of the lines to below the minimum width. In order to achieve the same effect you can increase the size of the image instead.

x = RandomReal[1, 10000];
y = RandomReal[1, 10000];
Show[ImageResize[Rasterize@ListLinePlot[{Thread@{x, y}}, ImageSize -> 10000], 300], ImageSize -> 300]

example

$\endgroup$
5
  • $\begingroup$ thx, but it has same problems as in previous answer (see comment) $\endgroup$
    – funnyp0ny
    Commented Nov 20, 2014 at 21:21
  • 1
    $\begingroup$ @funnypony The default colors in Mathematica are not the same as the default colors in Python. For example if you set the color to Blue (PlotStyle->Blue) they look similar. $\endgroup$
    – C. E.
    Commented Nov 20, 2014 at 21:24
  • $\begingroup$ yes, now i think its right (sorry i mark previous answer due to priority). i made some tests - it seems python draws a little denser towards center.. i.imgur.com/BfW29S9.png $\endgroup$
    – funnyp0ny
    Commented Nov 20, 2014 at 22:17
  • $\begingroup$ @funnypony Out of curiosity, why do you need to reproduce matplotlib's result with such fidelity? If it's really important to have the exact same output, why not just use matplotlib? Also, I guess matplotlib's output will depend on the precise rendering method and might easily change in the future. $\endgroup$
    – Szabolcs
    Commented Nov 21, 2014 at 16:50
  • $\begingroup$ @Szabolcs no, I don't need 'most idential plot ever') Initial idea was just to get something more or less similar to Python's plot - you can see my fail picture in the question, so solution with low opacity and pure blue color is completely fine. $\endgroup$
    – funnyp0ny
    Commented Nov 21, 2014 at 22:15
0
$\begingroup$

The OP has probably meant:

xy = RandomReal[1, {10000, 2}];
ListLinePlot[xy, PlotStyle -> [email protected]]

or

xy = RandomReal[1, {10000, 2}];
ListLinePlot[xy, PlotStyle -> Thickness@(10^-5)]

This seems to make a major difference, at least in Mathematica 13.2. Apparently "Thickness@10^-5" is not recognized properly.

$\endgroup$
3
  • $\begingroup$ Please include the plot to demonstarate that your approach works. $\endgroup$
    – bbgodfrey
    Commented Dec 6, 2023 at 1:58
  • $\begingroup$ Thickness@10^-5 evaluates to 1/Thickness[10]^5. It's a syntax typo. $\endgroup$ Commented Dec 6, 2023 at 11:57
  • $\begingroup$ Thanks for noticing that! It did work on some previous mathematica, where I'd actually tested the script, but not anymore. @ operator has high precedence, so it evaluates first exactly as Sjoerd Smit written. $\endgroup$
    – funnyp0ny
    Commented Dec 23, 2023 at 17:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.