22
$\begingroup$

I have manipulated an image and want to ListPlot it. However, the result is not to my liking because the conventions for drawing images and plots are different. Images have the origin at the top left and increase in Y downwards while plots have the origin at the bottom left and increase in Y upwards.

What is the easiest way to reconcile the difference, preferably without manipulating the data?

$\endgroup$
4
  • $\begingroup$ What do you mean by list plotting an image? $\endgroup$ Commented Mar 31, 2012 at 1:14
  • $\begingroup$ You start with an image, process it, and end up with an array which you display with ListPlot. $\endgroup$
    – Emre
    Commented Mar 31, 2012 at 1:15
  • $\begingroup$ Do you mean ListPlot or something like ArrayPlot or MatrixPlot. If you are refering to ArrayPlot/MatrixPlot then yes, they are different, the origin is in the bottom left vs. top left. You might try making your data an image again Image@data... $\endgroup$
    – s0rce
    Commented Mar 31, 2012 at 1:24
  • $\begingroup$ As a good ol' neuroscientist, I wish that DataReversed could be applied to ListPlot and friends (we flip the y-axis on EEG signals- tradition!!!). I've used the {#, -#2} & @@@ solution in the past, the Line[args___] seems cool, but I sure wish this was just 'fixed' so DataReversed->True would just 'work'. Sigh. $\endgroup$
    – flip
    Commented Apr 3, 2015 at 23:07

4 Answers 4

20
$\begingroup$

1: Reversing the image in a 2D plot (ArrayPlot or MatrixPlot)

Simply use DataReversed -> True. This has the effect of flipping the image along the horizontal axis. For example:

func[x_, y_] := Sinc[y ^2 + x^3];
data = Table[func[x,y], {x, -π, π, 0.1}, {y, -π, π, 0.1}];
ArrayPlot[data, DataReversed -> #] & /@ {True, False} // GraphicsRow

enter image description here

2: Changing the origin in a 1D plot (ListPlot or Plot)

Use AxesOrigin -> {x, y} to change the origin to where ever you like. For example:

Plot[Sin[x], {x, 0, 2 Pi}, AxesOrigin -> {0.5, 0.5}]

enter image description here

3: Changing the direction of the y-axis (or x-axis) in a 1D plot

Flipping the y-axis in a 1D plot is a bit more involved and is a very common approach in displaying depth plots. You can implement this in Mathematica by negating your input to ListPlot and assigning custom ticks with a function. Here's an example:

x = Sin /@ Range[0, 2 π, 0.1];
ListPlot[-x, Ticks -> {Automatic, Function[{xmin, xmax}, 
    Table[{i, -i, {0.02, 0}}, {i, N@FindDivisions[{xmin, xmax}, 10]}]]}]

enter image description here

$\endgroup$
0
12
$\begingroup$

I wrote some code for this a few years ago. Haven't looked at it in a long time but it may be useful. It is in the Wolfram library archive (that seems to have been all but abandoned by both users and Wolfram).

enter image description here

$\endgroup$
6
$\begingroup$

In the docs check the entry ImageData>Options>DataReversed and the first example in the section Properties & Relations to see if it helps with what you need.

$\endgroup$
3
  • $\begingroup$ I wish it did but I could not feed it to ListPlot. It says ArrayPlot et al only. Close... $\endgroup$
    – Emre
    Commented Mar 31, 2012 at 1:33
  • $\begingroup$ @Emre, a simple example showing how you go from an image to ListPlot would help everyone - what is the data in your ListPlot and how does it relate to the image? $\endgroup$
    – kglr
    Commented Mar 31, 2012 at 1:41
  • $\begingroup$ It's a 2D integer array. It can be from binarizing or segmenting the image. I want select all the pixels belonging to a particular cluster, using Position[filtered_image,n], which gives me a list of pixels, and run ListPlot. $\endgroup$
    – Emre
    Commented Mar 31, 2012 at 1:47
4
$\begingroup$

It's really not clear from your question what you want, but here is one simple interpretation:

dat = Table[{x, x^2 Exp[-x^2]}, {x, -5, 5, 0.1}];

ListLinePlot[dat, PlotRange -> All]

Mathematica graphics

ticks = Table[{-x, x}, {x, 0, 0.4, 0.05}];

ListLinePlot[{#, -#2} & @@@ dat, PlotRange -> All, Ticks -> {All, ticks}]

Mathematica graphics

This could be automated, but since I don't know if this is what you want I'm leaving it there for now.

$\endgroup$
3
  • 1
    $\begingroup$ Purely graphical solution without touching data: ListLinePlot[dat, PlotRange -> All] /. Line[args___] :> Scale[Line[args], {1, -1}]. PlotRange goes nuts though (Probably a bug). $\endgroup$ Commented Mar 31, 2012 at 1:38
  • 1
    $\begingroup$ @Yu-SungChang ListLinePlot is turning PlotRange -> All into explicit lower and upper bounds, which I don't consider to be a bug. Sometimes it's helpful, and sometimes it's not. $\endgroup$ Commented Mar 31, 2012 at 3:20
  • $\begingroup$ I actually ended up going with Apply[{#1, -#2}], as suggested here, but there were several useful answers and comments so I wanted to thank everyone. $\endgroup$
    – Emre
    Commented Apr 1, 2012 at 1:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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