4
$\begingroup$

I have a file I import and read into a table of $2 \times n$. I can plot this data using the following code:

directory = "c:\nameofdirectory";
SetDirectory[directory];
filenames = FileNames[];
readlist = ToString[filenames[[1]]];
table = OpenRead[readlist];
data = ReadList[table, {Number, Number}];
Close[table];

ListPlot[data, Frame -> True, PlotRange -> {All, All}, Joined -> True, 
  FrameLabel -> {"Voltage (V)", "Current (A)"}];

but the $y$-axis is order of $10^{-6} A$. I'd prefer to have my $y$-data scaled by $10^{-6}$ then label my axis is microA instead of A. I've tried using Ticks but I don't really understand how that works (it never changes my plot at all when I use it).

If there's no easy way to do this, can someone tell me how to directly divide my $y$-values from the input? I can separate the $y$-values from "data" and divide them using

xdat = List[];
ydat = List[];
For[j = 1, j < Length[data] + 1, j++,
    AppendTo[xdat, data[[j]][[1]]];
    AppendTo[ydat, data[[j]][[2]]];
   ];

y=ydat/10^-6;

but I don't know how to place them back into the form as before so that it can be easily plotted with ListPlot.

$\endgroup$
1
  • 1
    $\begingroup$ Welcome at Mathematica SE! You should try to simplify your post to provide minimal working example which reproduces Your issue. Have a look how to format a post mathematica.stackexchange.com/editing-help $\endgroup$
    – mmal
    Commented Dec 2, 2013 at 0:14

2 Answers 2

7
$\begingroup$

There are a lot of ways. For example:

data = Table[{x, 10^-6  Sin[x]}, {x, 0, 1, 0.01}];
ListPlot[data /. {x_, y_} :> {x, 10^6 y}, Frame -> True, 
        PlotRange -> {All, All}, Joined -> True, 
        FrameLabel -> {"Voltage (V)", "Current (Ma)"}]

Mathematica graphics

$\endgroup$
2
  • $\begingroup$ thanks so much! that is exactly what i wanted. $\endgroup$
    – issk2q
    Commented Dec 2, 2013 at 15:47
  • $\begingroup$ @issk2q when using named patterns in a replacement rule use RuleDelayed (short form :>) unless you specifically know otherwise. It will save you headache. $\endgroup$
    – Mr.Wizard
    Commented Dec 2, 2013 at 18:56
5
$\begingroup$

belisarius showed replacement rules. I favor Map or Apply for such operations. For large data Transpose will be of use. Finally I was remiss not to mention the Dot operator in my original answer. Here are some examples, borrowing belisarius's data source.

First I create a larger data set so that performance differences are apparent:

data = {#, 1*^-6 Sin@#}\[Transpose] & @ Range[0, 2 Pi, 0.00001];

This uses the listability of Sin for greater performance, much as I will show below.

You can use Apply at level one, shorthand @@@ for a concise operation:

data1 = {#, 1*^6 #2} & @@@ data; // Timing // First
0.359

Map is a bit more efficient because it does not unpack the array:

data2 = {#[[1]], 1*^6 #[[2]]} & /@ data; // Timing // First
0.156

An orders of magnitude faster than either method above is to transpose the data, scale it using listable functions, and transpose again to put it back in the original form:

data3 = {#, 1*^6 #2}\[Transpose] & @@ (data\[Transpose]); // Timing // First
0.015

(See the documentation for \[Transpose].)

Equally fast for this particular task is the Dot operator:

data = data.{{1, 0}, {0, 1*^6}}; // Timing // First
0.015

It is not as flexible as the transpose method however, as that method can work with any scaling method and not merely simple multiplication.

The operations are equivalent:

data1 === data2 === data3 === data4
True
$\endgroup$

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.