4

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.

Svend Tveskæg
  • 425
  • 5
  • 14
issk2q
  • 43
  • 1
  • 3
  • 1
    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 http://mathematica.stackexchange.com/editing-help – mmal Dec 02 '13 at 00:14

2 Answers2

7

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

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
Dr. belisarius
  • 115,881
  • 13
  • 203
  • 453
  • thanks so much! that is exactly what i wanted. – issk2q Dec 02 '13 at 15:47
  • @issk2q when using named patterns in a replacement rule use RuleDelayed (short form :>) unless you specifically know otherwise. It will save you headache. – Mr.Wizard Dec 02 '13 at 18:56
5

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
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371