From: Dawid W. <daw...@cs...> - 2005-01-04 22:14:05
|
Hi there, I would appreciate if somebody knowledgeable could help be out with this one: I have a bar chart with simple data that is numeric (both x and y axis) and looks something like shown below: 0 138 1 58047 2 13724 3 5679 ... (continues) The X axis is a graph.axis.bar. The problem is that axis labels are shown as floating point integers: 0.0, 1.0, 2.0, 3.0 etc and I need them to be exactly the way they were present in the input file. The same problem applies to labels but above bars using graph.style.text -- again, the label value is formatted as a floating point number instead of an integer (138.0, 58047.0 etc in the example above). looked for a texter that these two use, but I must admit I failed... I would appreciate if somebody could enlighten me how to deal with this problem. Dawid |
From: Andre W. <wo...@us...> - 2005-01-05 13:28:52
|
Hi Dawid, On 04.01.05, Dawid Weiss wrote: > I would appreciate if somebody knowledgeable could help be out with this > one: > > I have a bar chart with simple data that is numeric (both x and y axis) > and looks something like shown below: > > 0 138 > 1 58047 > 2 13724 > 3 5679 > ... (continues) > > The X axis is a graph.axis.bar. The problem is that axis labels are > shown as floating point integers: 0.0, 1.0, 2.0, 3.0 etc and I need them > to be exactly the way they were present in the input file. The same > problem applies to labels but above bars using graph.style.text -- > again, the label value is formatted as a floating point number instead > of an integer (138.0, 58047.0 etc in the example above). > > looked for a texter that these two use, but I must admit I failed... I > would appreciate if somebody could enlighten me how to deal with this > problem. First of all it has nothing to do with a texter, since the bar axis doesn't have a texter. (I'm sorry for the confusion.) A bar axis just doesn't need to have a texter, since it doesn't even have a partitioner. A bar axis just enumerates some values and stores the values for later reference. The values are written by the bar axis painter (pyx.graph.axis.painter.bar). This bar axis painter needs to pass the values to (La)TeX by means of the text module, and for that it needs to have strings which are generated by str(). For the text graph style its about the same. And the call of the string method leads to the ".0". And that's because of the fact, that the data file reader tries to convert everything into floats. Its only aware of two different types: floats and strings. (And None to be complete, but None occurs only, when you do not provide the same number of values per line to fill the missing columns.) (We might discuss, whether this conversion to floats is a good idea, but there are some arguments for it. I would appreciate this discussion, since it was *never* discussed before. But back to the issue.) There are several ways out. First, when you use the line number column (it has number "0"), you'll find integer numbers in there. But they'll always start from 1. Second, you can quote the numbers in your data file like in: "0" 138 "1" 58047 "2" 13724 "3" 5679 ... (continues) This marks the numbers in the first column to be strings. A third possibility would be to take care of the data reading yourself. While this might sound difficult, it isn't at all. The modified version of the minimal example is as simple as: from pyx import * class myfile(graph.data.list): def __init__(self, filename, **kwargs): def convert(line): items = line.split() yield items[0] for item in items[1:]: yield float(item) points = [list(convert(line)) for line in open(filename)] graph.data.list.__init__(self, points, **kwargs) g = graph.graphxy(width=8, x=graph.axis.bar()) g.plot(myfile("bar.dat", xname=1, y=2), [graph.style.bar()]) g.writeEPSfile("minimal") This version will always keep the first column as string values. Sure, it's not that full functional like the orginial file reader (column names, error tolerance for invalid numbers, comment lines, mathematics on columns, by passing it thru a graph.data.data instance etc.). But whenever you need such a feature it can be easily added to myfile. And last but not least dirty tricks are possible as well. For two-column data files you could do: import re from pyx import * g = graph.graphxy(width=8, x=graph.axis.bar()) g.plot(graph.data.file("bar.dat", xname=1, y=2, stringpattern=re.compile(r"\s*(.*?)\s+")), [graph.style.bar()]) g.writeEPSfile("minimal") For different number of columns the string pattern could be adjusted as well. (I guess you'll break the automatic column titles by that, but you may not use that feature anyway.) HTH, André -- by _ _ _ Dr. André Wobst / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript figures with Python & TeX (_/ \_)_/\_/ visit http://pyx.sourceforge.net/ |