|
From: Christer <chm...@st...> - 2010-05-20 13:43:54
|
Thank you for the help, I never knew what the symlog flag did actually.
However, there is still a slight problem:
=====================================================
x = array([0,1,2,4,6,9,12,24])
y = array([1000000, 500000, 100000, 100, 5, 1, 1, 1])
subplot(111)
plot(x, y)
yscale('symlog')
xscale=('linear')
ylim(-1,10000000)
show()
=====================================================
The plot looks exactly like I want it, the problem is when I change
the "1"'s to "0"'s in the y-array, then I get a:
File "C:\Python26\lib\site-packages\matplotlib\ticker.py", line 1029,
in is_decade
lx = math.log(x)/math.log(base)
ValueError: math domain error
I suppose that means somewhere a log(0) is attempted. This kind of
defeats the purpose...
/C
Quoting Eric Firing <ef...@ha...>:
> On 05/19/2010 10:28 AM, Benjamin Root wrote:
>> Maybe I am misunderstanding your problem, but you can select
'semilog'
>> for the x/yscale parameter.
>
> You mean "symlog".
>
> See
>
http://matplotlib.sourceforge.net/examples/pylab_examples/symlog_demo.html
>
> Although the example doesn't show it, the axis limits don't have to be
> symmetric. For example, on the top plot, you can use
>
> gca().set_xlim([0, 100])
>
> to show only the right-hand side.
>
> Eric
>
>
>>
>> Ben Root
>>
>> On Wed, May 19, 2010 at 7:03 AM, Christer Malmberg
>> <Chr...@st...
>> <mailto:Chr...@st...>> wrote:
>>
>> Hi,
>>
>> my problem is that I need a graph with a discontinous y-axis. Let
me
>> explain the problem: in my field (microbiology) the data
generated
>> from for example growth assays have a huge range (10^0-10^9),
which
>> has to be plotted on a semilogy style plot (cell concentration
vs.
>> time). The problem is that 0 cells is a useful number to plot
>> (indicates cell concentration lower than detection limit), but of
>> course not possible to show in a log diagram. This is easily
solved on
>> old-style logarithmic graph paper; since the data will be either
0, or
>> >1 it is customary just to draw a zero x-axis at 10^-1 on the
paper
>> and that's that. On the computer, this is extremely hard. Most
people
>> I know resort to various tricks in Excel, such as entering a
small
>> number (0.001 etc) and starting the y-axis range from 10^1 to
hide the
>> problem. This makes excel draw a line, instead of leaving out the
dot
>> and line entirely. The part of the curve below the x-axis is then
>> manually cut off in a suitable image editor. Needless to say,
this is
>> extremely kludgy. Even professional graphing packages like
Graphpad
>> Prism resort to similar kludges (re-define 0 values to 0.1,
change the
>> y-axis tick label to "0" etc.) This problem of course exists in
other
>> fields, while investigating a solution I found a guy who worked
with
>> aerosol contamination in clean rooms, and he needed to plot
values
>> logarithmically, at the same time as showing detector noise
around
>> 1-10 particles. He solved it by the same trick I would like to do
in
>> Matplotlib, namely plotting a standard semilogy plot but with the
>> 10^-1 to 10^0 decade being replaced by a 0-1 linear axis on the
same
>> side.
>>
>> The guy in this post has the same problem and a useful example:
>> http://ubuntuforums.org/showthread.php?t=394851
>>
>> His partial solution is quite bad though, and I just got stuck
while
>> trying to improve it. I looked around the gallery for useful
examples,
>> and the closest I could find is the twinx/twiny function, but I
didn't
>> manage a plot that put one data curve across both axes.
>>
>> This code gives an image that maybe explains what I'm trying to
do:
>>
>> =======================================
>> t = array([0,1,2,4,6,9,12,24])
>> y = array([1000000, 500000, 100000, 100, 5, 1, 0, 0])
>> subplot(111, xscale="linear", yscale="log")
>> errorbar(x, y, yerr=0.4*y)
>> linbit = axes([0.125, 0.1, 0.775, 0.1],frameon=False)
>> linbit.xaxis.set_visible(False)
>> for tl in linbit.get_yticklabels():
>> tl.set_color('r')
>> show()
>> =======================================
>>
>> (the y=0 points should be plotted and connected to the line in
the
>> log part)
>>
>> Is this possible to do in matplotlib? Could someone give me a
pointer
>> on how to go on?
>>
>> Sorry for the long mail,
>>
>> /C
>>
>>
>>
>>
------------------------------------------------------------------------------
>>
>> _______________________________________________
>> Matplotlib-users mailing list
>> Mat...@li...
>> <mailto:Mat...@li...>
>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>>
>>
>>
>>
>>
------------------------------------------------------------------------------
>>
>>
>>
>>
>> _______________________________________________
>> Matplotlib-users mailing list
>> Mat...@li...
>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>
>
>
------------------------------------------------------------------------------
>
> _______________________________________________
> Matplotlib-users mailing list
> Mat...@li...
> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>
|
|
From: Michael D. <md...@st...> - 2010-05-20 14:02:51
|
Yep. That's a bug. Here's a patch to fix it:
ndex: lib/matplotlib/ticker.py
===================================================================
--- lib/matplotlib/ticker.py (revision 8323)
+++ lib/matplotlib/ticker.py (working copy)
@@ -1178,16 +1178,21 @@
def decade_down(x, base=10):
'floor x to the nearest lower decade'
-
+ if x == 0.0:
+ return -base
lx = math.floor(math.log(x)/math.log(base))
return base**lx
def decade_up(x, base=10):
'ceil x to the nearest higher decade'
+ if x == 0.0:
+ return base
lx = math.ceil(math.log(x)/math.log(base))
return base**lx
def is_decade(x,base=10):
+ if x == 0.0:
+ return True
lx = math.log(x)/math.log(base)
return lx==int(lx)
Mike
On 05/20/2010 09:43 AM, Christer wrote:
> Thank you for the help, I never knew what the symlog flag did actually.
>
> However, there is still a slight problem:
>
> =====================================================
> x = array([0,1,2,4,6,9,12,24])
> y = array([1000000, 500000, 100000, 100, 5, 1, 1, 1])
> subplot(111)
> plot(x, y)
> yscale('symlog')
> xscale=('linear')
> ylim(-1,10000000)
> show()
> =====================================================
>
> The plot looks exactly like I want it, the problem is when I change
> the "1"'s to "0"'s in the y-array, then I get a:
>
> File "C:\Python26\lib\site-packages\matplotlib\ticker.py", line 1029,
> in is_decade
> lx = math.log(x)/math.log(base)
> ValueError: math domain error
>
> I suppose that means somewhere a log(0) is attempted. This kind of
> defeats the purpose...
>
> /C
>
> Quoting Eric Firing<ef...@ha...>:
>
>
>> On 05/19/2010 10:28 AM, Benjamin Root wrote:
>>
>>> Maybe I am misunderstanding your problem, but you can select
>>>
> 'semilog'
>
>>> for the x/yscale parameter.
>>>
>> You mean "symlog".
>>
>> See
>>
>>
> http://matplotlib.sourceforge.net/examples/pylab_examples/symlog_demo.html
>
>> Although the example doesn't show it, the axis limits don't have to be
>> symmetric. For example, on the top plot, you can use
>>
>> gca().set_xlim([0, 100])
>>
>> to show only the right-hand side.
>>
>> Eric
>>
>>
>>
>>> Ben Root
>>>
>>> On Wed, May 19, 2010 at 7:03 AM, Christer Malmberg
>>> <Chr...@st...
>>> <mailto:Chr...@st...>> wrote:
>>>
>>> Hi,
>>>
>>> my problem is that I need a graph with a discontinous y-axis. Let
>>>
> me
>
>>> explain the problem: in my field (microbiology) the data
>>>
> generated
>
>>> from for example growth assays have a huge range (10^0-10^9),
>>>
> which
>
>>> has to be plotted on a semilogy style plot (cell concentration
>>>
> vs.
>
>>> time). The problem is that 0 cells is a useful number to plot
>>> (indicates cell concentration lower than detection limit), but of
>>> course not possible to show in a log diagram. This is easily
>>>
> solved on
>
>>> old-style logarithmic graph paper; since the data will be either
>>>
> 0, or
>
>>> >1 it is customary just to draw a zero x-axis at 10^-1 on the
>>>
> paper
>
>>> and that's that. On the computer, this is extremely hard. Most
>>>
> people
>
>>> I know resort to various tricks in Excel, such as entering a
>>>
> small
>
>>> number (0.001 etc) and starting the y-axis range from 10^1 to
>>>
> hide the
>
>>> problem. This makes excel draw a line, instead of leaving out the
>>>
> dot
>
>>> and line entirely. The part of the curve below the x-axis is then
>>> manually cut off in a suitable image editor. Needless to say,
>>>
> this is
>
>>> extremely kludgy. Even professional graphing packages like
>>>
> Graphpad
>
>>> Prism resort to similar kludges (re-define 0 values to 0.1,
>>>
> change the
>
>>> y-axis tick label to "0" etc.) This problem of course exists in
>>>
> other
>
>>> fields, while investigating a solution I found a guy who worked
>>>
> with
>
>>> aerosol contamination in clean rooms, and he needed to plot
>>>
> values
>
>>> logarithmically, at the same time as showing detector noise
>>>
> around
>
>>> 1-10 particles. He solved it by the same trick I would like to do
>>>
> in
>
>>> Matplotlib, namely plotting a standard semilogy plot but with the
>>> 10^-1 to 10^0 decade being replaced by a 0-1 linear axis on the
>>>
> same
>
>>> side.
>>>
>>> The guy in this post has the same problem and a useful example:
>>> http://ubuntuforums.org/showthread.php?t=394851
>>>
>>> His partial solution is quite bad though, and I just got stuck
>>>
> while
>
>>> trying to improve it. I looked around the gallery for useful
>>>
> examples,
>
>>> and the closest I could find is the twinx/twiny function, but I
>>>
> didn't
>
>>> manage a plot that put one data curve across both axes.
>>>
>>> This code gives an image that maybe explains what I'm trying to
>>>
> do:
>
>>> =======================================
>>> t = array([0,1,2,4,6,9,12,24])
>>> y = array([1000000, 500000, 100000, 100, 5, 1, 0, 0])
>>> subplot(111, xscale="linear", yscale="log")
>>> errorbar(x, y, yerr=0.4*y)
>>> linbit = axes([0.125, 0.1, 0.775, 0.1],frameon=False)
>>> linbit.xaxis.set_visible(False)
>>> for tl in linbit.get_yticklabels():
>>> tl.set_color('r')
>>> show()
>>> =======================================
>>>
>>> (the y=0 points should be plotted and connected to the line in
>>>
> the
>
>>> log part)
>>>
>>> Is this possible to do in matplotlib? Could someone give me a
>>>
> pointer
>
>>> on how to go on?
>>>
>>> Sorry for the long mail,
>>>
>>> /C
>>>
>>>
>>>
>>>
>>>
> ------------------------------------------------------------------------------
>
>>> _______________________________________________
>>> Matplotlib-users mailing list
>>> Mat...@li...
>>> <mailto:Mat...@li...>
>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>>>
>>>
>>>
>>>
>>>
>>>
> ------------------------------------------------------------------------------
>
>>>
>>>
>>>
>>> _______________________________________________
>>> Matplotlib-users mailing list
>>> Mat...@li...
>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>>>
>>
>>
>>
> ------------------------------------------------------------------------------
>
>> _______________________________________________
>> Matplotlib-users mailing list
>> Mat...@li...
>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>>
>>
>
>
> ------------------------------------------------------------------------------
>
> _______________________________________________
> Matplotlib-users mailing list
> Mat...@li...
> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>
--
Michael Droettboom
Science Software Branch
Space Telescope Science Institute
Baltimore, Maryland, USA
|
|
From: Benjamin R. <ben...@ou...> - 2010-05-20 14:09:24
|
Do we really want to depend on a floating point equality?
Ben Root
On Thu, May 20, 2010 at 9:02 AM, Michael Droettboom <md...@st...> wrote:
> Yep. That's a bug. Here's a patch to fix it:
>
> ndex: lib/matplotlib/ticker.py
> ===================================================================
> --- lib/matplotlib/ticker.py (revision 8323)
> +++ lib/matplotlib/ticker.py (working copy)
> @@ -1178,16 +1178,21 @@
>
> def decade_down(x, base=10):
> 'floor x to the nearest lower decade'
> -
> + if x == 0.0:
> + return -base
> lx = math.floor(math.log(x)/math.log(base))
> return base**lx
>
> def decade_up(x, base=10):
> 'ceil x to the nearest higher decade'
> + if x == 0.0:
> + return base
> lx = math.ceil(math.log(x)/math.log(base))
> return base**lx
>
> def is_decade(x,base=10):
> + if x == 0.0:
> + return True
> lx = math.log(x)/math.log(base)
> return lx==int(lx)
>
> Mike
>
> On 05/20/2010 09:43 AM, Christer wrote:
> > Thank you for the help, I never knew what the symlog flag did actually.
> >
> > However, there is still a slight problem:
> >
> > =====================================================
> > x = array([0,1,2,4,6,9,12,24])
> > y = array([1000000, 500000, 100000, 100, 5, 1, 1, 1])
> > subplot(111)
> > plot(x, y)
> > yscale('symlog')
> > xscale=('linear')
> > ylim(-1,10000000)
> > show()
> > =====================================================
> >
> > The plot looks exactly like I want it, the problem is when I change
> > the "1"'s to "0"'s in the y-array, then I get a:
> >
> > File "C:\Python26\lib\site-packages\matplotlib\ticker.py", line 1029,
> > in is_decade
> > lx = math.log(x)/math.log(base)
> > ValueError: math domain error
> >
> > I suppose that means somewhere a log(0) is attempted. This kind of
> > defeats the purpose...
> >
> > /C
> >
> > Quoting Eric Firing<ef...@ha...>:
> >
> >
> >> On 05/19/2010 10:28 AM, Benjamin Root wrote:
> >>
> >>> Maybe I am misunderstanding your problem, but you can select
> >>>
> > 'semilog'
> >
> >>> for the x/yscale parameter.
> >>>
> >> You mean "symlog".
> >>
> >> See
> >>
> >>
> >
> http://matplotlib.sourceforge.net/examples/pylab_examples/symlog_demo.html
> >
> >> Although the example doesn't show it, the axis limits don't have to be
> >> symmetric. For example, on the top plot, you can use
> >>
> >> gca().set_xlim([0, 100])
> >>
> >> to show only the right-hand side.
> >>
> >> Eric
> >>
> >>
> >>
> >>> Ben Root
> >>>
> >>> On Wed, May 19, 2010 at 7:03 AM, Christer Malmberg
> >>> <Chr...@st...
> >>> <mailto:Chr...@st...>> wrote:
> >>>
> >>> Hi,
> >>>
> >>> my problem is that I need a graph with a discontinous y-axis. Let
> >>>
> > me
> >
> >>> explain the problem: in my field (microbiology) the data
> >>>
> > generated
> >
> >>> from for example growth assays have a huge range (10^0-10^9),
> >>>
> > which
> >
> >>> has to be plotted on a semilogy style plot (cell concentration
> >>>
> > vs.
> >
> >>> time). The problem is that 0 cells is a useful number to plot
> >>> (indicates cell concentration lower than detection limit), but of
> >>> course not possible to show in a log diagram. This is easily
> >>>
> > solved on
> >
> >>> old-style logarithmic graph paper; since the data will be either
> >>>
> > 0, or
> >
> >>> >1 it is customary just to draw a zero x-axis at 10^-1 on the
> >>>
> > paper
> >
> >>> and that's that. On the computer, this is extremely hard. Most
> >>>
> > people
> >
> >>> I know resort to various tricks in Excel, such as entering a
> >>>
> > small
> >
> >>> number (0.001 etc) and starting the y-axis range from 10^1 to
> >>>
> > hide the
> >
> >>> problem. This makes excel draw a line, instead of leaving out the
> >>>
> > dot
> >
> >>> and line entirely. The part of the curve below the x-axis is then
> >>> manually cut off in a suitable image editor. Needless to say,
> >>>
> > this is
> >
> >>> extremely kludgy. Even professional graphing packages like
> >>>
> > Graphpad
> >
> >>> Prism resort to similar kludges (re-define 0 values to 0.1,
> >>>
> > change the
> >
> >>> y-axis tick label to "0" etc.) This problem of course exists in
> >>>
> > other
> >
> >>> fields, while investigating a solution I found a guy who worked
> >>>
> > with
> >
> >>> aerosol contamination in clean rooms, and he needed to plot
> >>>
> > values
> >
> >>> logarithmically, at the same time as showing detector noise
> >>>
> > around
> >
> >>> 1-10 particles. He solved it by the same trick I would like to do
> >>>
> > in
> >
> >>> Matplotlib, namely plotting a standard semilogy plot but with the
> >>> 10^-1 to 10^0 decade being replaced by a 0-1 linear axis on the
> >>>
> > same
> >
> >>> side.
> >>>
> >>> The guy in this post has the same problem and a useful example:
> >>> http://ubuntuforums.org/showthread.php?t=394851
> >>>
> >>> His partial solution is quite bad though, and I just got stuck
> >>>
> > while
> >
> >>> trying to improve it. I looked around the gallery for useful
> >>>
> > examples,
> >
> >>> and the closest I could find is the twinx/twiny function, but I
> >>>
> > didn't
> >
> >>> manage a plot that put one data curve across both axes.
> >>>
> >>> This code gives an image that maybe explains what I'm trying to
> >>>
> > do:
> >
> >>> =======================================
> >>> t = array([0,1,2,4,6,9,12,24])
> >>> y = array([1000000, 500000, 100000, 100, 5, 1, 0, 0])
> >>> subplot(111, xscale="linear", yscale="log")
> >>> errorbar(x, y, yerr=0.4*y)
> >>> linbit = axes([0.125, 0.1, 0.775, 0.1],frameon=False)
> >>> linbit.xaxis.set_visible(False)
> >>> for tl in linbit.get_yticklabels():
> >>> tl.set_color('r')
> >>> show()
> >>> =======================================
> >>>
> >>> (the y=0 points should be plotted and connected to the line in
> >>>
> > the
> >
> >>> log part)
> >>>
> >>> Is this possible to do in matplotlib? Could someone give me a
> >>>
> > pointer
> >
> >>> on how to go on?
> >>>
> >>> Sorry for the long mail,
> >>>
> >>> /C
> >>>
> >>>
> >>>
> >>>
> >>>
> >
> ------------------------------------------------------------------------------
> >
> >>> _______________________________________________
> >>> Matplotlib-users mailing list
> >>> Mat...@li...
> >>> <mailto:Mat...@li...>
> >>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >
> ------------------------------------------------------------------------------
> >
> >>>
> >>>
> >>>
> >>> _______________________________________________
> >>> Matplotlib-users mailing list
> >>> Mat...@li...
> >>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
> >>>
> >>
> >>
> >>
> >
> ------------------------------------------------------------------------------
> >
> >> _______________________________________________
> >> Matplotlib-users mailing list
> >> Mat...@li...
> >> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
> >>
> >>
> >
> >
> >
> ------------------------------------------------------------------------------
> >
> > _______________________________________________
> > Matplotlib-users mailing list
> > Mat...@li...
> > https://lists.sourceforge.net/lists/listinfo/matplotlib-users
> >
>
>
> --
> Michael Droettboom
> Science Software Branch
> Space Telescope Science Institute
> Baltimore, Maryland, USA
>
>
>
> ------------------------------------------------------------------------------
>
> _______________________________________________
> Matplotlib-users mailing list
> Mat...@li...
> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>
|
|
From: Michael D. <md...@st...> - 2010-05-20 14:22:52
|
In this case, yes. The assumption of these (private) functions is that
x will be non-negative. The only case where we need to worry about log
raising an exception is with exactly 0.
Mike
On 05/20/2010 10:08 AM, Benjamin Root wrote:
> Do we really want to depend on a floating point equality?
>
> Ben Root
>
> On Thu, May 20, 2010 at 9:02 AM, Michael Droettboom<md...@st...> wrote:
>
>
>> Yep. That's a bug. Here's a patch to fix it:
>>
>> ndex: lib/matplotlib/ticker.py
>> ===================================================================
>> --- lib/matplotlib/ticker.py (revision 8323)
>> +++ lib/matplotlib/ticker.py (working copy)
>> @@ -1178,16 +1178,21 @@
>>
>> def decade_down(x, base=10):
>> 'floor x to the nearest lower decade'
>> -
>> + if x == 0.0:
>> + return -base
>> lx = math.floor(math.log(x)/math.log(base))
>> return base**lx
>>
>> def decade_up(x, base=10):
>> 'ceil x to the nearest higher decade'
>> + if x == 0.0:
>> + return base
>> lx = math.ceil(math.log(x)/math.log(base))
>> return base**lx
>>
>> def is_decade(x,base=10):
>> + if x == 0.0:
>> + return True
>> lx = math.log(x)/math.log(base)
>> return lx==int(lx)
>>
>> Mike
>>
>> On 05/20/2010 09:43 AM, Christer wrote:
>>
>>> Thank you for the help, I never knew what the symlog flag did actually.
>>>
>>> However, there is still a slight problem:
>>>
>>> =====================================================
>>> x = array([0,1,2,4,6,9,12,24])
>>> y = array([1000000, 500000, 100000, 100, 5, 1, 1, 1])
>>> subplot(111)
>>> plot(x, y)
>>> yscale('symlog')
>>> xscale=('linear')
>>> ylim(-1,10000000)
>>> show()
>>> =====================================================
>>>
>>> The plot looks exactly like I want it, the problem is when I change
>>> the "1"'s to "0"'s in the y-array, then I get a:
>>>
>>> File "C:\Python26\lib\site-packages\matplotlib\ticker.py", line 1029,
>>> in is_decade
>>> lx = math.log(x)/math.log(base)
>>> ValueError: math domain error
>>>
>>> I suppose that means somewhere a log(0) is attempted. This kind of
>>> defeats the purpose...
>>>
>>> /C
>>>
>>> Quoting Eric Firing<ef...@ha...>:
>>>
>>>
>>>
>>>> On 05/19/2010 10:28 AM, Benjamin Root wrote:
>>>>
>>>>
>>>>> Maybe I am misunderstanding your problem, but you can select
>>>>>
>>>>>
>>> 'semilog'
>>>
>>>
>>>>> for the x/yscale parameter.
>>>>>
>>>>>
>>>> You mean "symlog".
>>>>
>>>> See
>>>>
>>>>
>>>>
>>>
>> http://matplotlib.sourceforge.net/examples/pylab_examples/symlog_demo.html
>>
>>>
>>>> Although the example doesn't show it, the axis limits don't have to be
>>>> symmetric. For example, on the top plot, you can use
>>>>
>>>> gca().set_xlim([0, 100])
>>>>
>>>> to show only the right-hand side.
>>>>
>>>> Eric
>>>>
>>>>
>>>>
>>>>
>>>>> Ben Root
>>>>>
>>>>> On Wed, May 19, 2010 at 7:03 AM, Christer Malmberg
>>>>> <Chr...@st...
>>>>> <mailto:Chr...@st...>> wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> my problem is that I need a graph with a discontinous y-axis. Let
>>>>>
>>>>>
>>> me
>>>
>>>
>>>>> explain the problem: in my field (microbiology) the data
>>>>>
>>>>>
>>> generated
>>>
>>>
>>>>> from for example growth assays have a huge range (10^0-10^9),
>>>>>
>>>>>
>>> which
>>>
>>>
>>>>> has to be plotted on a semilogy style plot (cell concentration
>>>>>
>>>>>
>>> vs.
>>>
>>>
>>>>> time). The problem is that 0 cells is a useful number to plot
>>>>> (indicates cell concentration lower than detection limit), but of
>>>>> course not possible to show in a log diagram. This is easily
>>>>>
>>>>>
>>> solved on
>>>
>>>
>>>>> old-style logarithmic graph paper; since the data will be either
>>>>>
>>>>>
>>> 0, or
>>>
>>>
>>>>> >1 it is customary just to draw a zero x-axis at 10^-1 on the
>>>>>
>>>>>
>>> paper
>>>
>>>
>>>>> and that's that. On the computer, this is extremely hard. Most
>>>>>
>>>>>
>>> people
>>>
>>>
>>>>> I know resort to various tricks in Excel, such as entering a
>>>>>
>>>>>
>>> small
>>>
>>>
>>>>> number (0.001 etc) and starting the y-axis range from 10^1 to
>>>>>
>>>>>
>>> hide the
>>>
>>>
>>>>> problem. This makes excel draw a line, instead of leaving out the
>>>>>
>>>>>
>>> dot
>>>
>>>
>>>>> and line entirely. The part of the curve below the x-axis is then
>>>>> manually cut off in a suitable image editor. Needless to say,
>>>>>
>>>>>
>>> this is
>>>
>>>
>>>>> extremely kludgy. Even professional graphing packages like
>>>>>
>>>>>
>>> Graphpad
>>>
>>>
>>>>> Prism resort to similar kludges (re-define 0 values to 0.1,
>>>>>
>>>>>
>>> change the
>>>
>>>
>>>>> y-axis tick label to "0" etc.) This problem of course exists in
>>>>>
>>>>>
>>> other
>>>
>>>
>>>>> fields, while investigating a solution I found a guy who worked
>>>>>
>>>>>
>>> with
>>>
>>>
>>>>> aerosol contamination in clean rooms, and he needed to plot
>>>>>
>>>>>
>>> values
>>>
>>>
>>>>> logarithmically, at the same time as showing detector noise
>>>>>
>>>>>
>>> around
>>>
>>>
>>>>> 1-10 particles. He solved it by the same trick I would like to do
>>>>>
>>>>>
>>> in
>>>
>>>
>>>>> Matplotlib, namely plotting a standard semilogy plot but with the
>>>>> 10^-1 to 10^0 decade being replaced by a 0-1 linear axis on the
>>>>>
>>>>>
>>> same
>>>
>>>
>>>>> side.
>>>>>
>>>>> The guy in this post has the same problem and a useful example:
>>>>> http://ubuntuforums.org/showthread.php?t=394851
>>>>>
>>>>> His partial solution is quite bad though, and I just got stuck
>>>>>
>>>>>
>>> while
>>>
>>>
>>>>> trying to improve it. I looked around the gallery for useful
>>>>>
>>>>>
>>> examples,
>>>
>>>
>>>>> and the closest I could find is the twinx/twiny function, but I
>>>>>
>>>>>
>>> didn't
>>>
>>>
>>>>> manage a plot that put one data curve across both axes.
>>>>>
>>>>> This code gives an image that maybe explains what I'm trying to
>>>>>
>>>>>
>>> do:
>>>
>>>
>>>>> =======================================
>>>>> t = array([0,1,2,4,6,9,12,24])
>>>>> y = array([1000000, 500000, 100000, 100, 5, 1, 0, 0])
>>>>> subplot(111, xscale="linear", yscale="log")
>>>>> errorbar(x, y, yerr=0.4*y)
>>>>> linbit = axes([0.125, 0.1, 0.775, 0.1],frameon=False)
>>>>> linbit.xaxis.set_visible(False)
>>>>> for tl in linbit.get_yticklabels():
>>>>> tl.set_color('r')
>>>>> show()
>>>>> =======================================
>>>>>
>>>>> (the y=0 points should be plotted and connected to the line in
>>>>>
>>>>>
>>> the
>>>
>>>
>>>>> log part)
>>>>>
>>>>> Is this possible to do in matplotlib? Could someone give me a
>>>>>
>>>>>
>>> pointer
>>>
>>>
>>>>> on how to go on?
>>>>>
>>>>> Sorry for the long mail,
>>>>>
>>>>> /C
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>
>> ------------------------------------------------------------------------------
>>
>>>
>>>>> _______________________________________________
>>>>> Matplotlib-users mailing list
>>>>> Mat...@li...
>>>>> <mailto:Mat...@li...>
>>>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>
>> ------------------------------------------------------------------------------
>>
>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Matplotlib-users mailing list
>>>>> Mat...@li...
>>>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>
>> ------------------------------------------------------------------------------
>>
>>>
>>>> _______________________________________________
>>>> Matplotlib-users mailing list
>>>> Mat...@li...
>>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>>>>
>>>>
>>>>
>>>
>>>
>>>
>> ------------------------------------------------------------------------------
>>
>>> _______________________________________________
>>> Matplotlib-users mailing list
>>> Mat...@li...
>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>>>
>>>
>>
>> --
>> Michael Droettboom
>> Science Software Branch
>> Space Telescope Science Institute
>> Baltimore, Maryland, USA
>>
>>
>>
>> ------------------------------------------------------------------------------
>>
>> _______________________________________________
>> Matplotlib-users mailing list
>> Mat...@li...
>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>>
>>
>
--
Michael Droettboom
Science Software Branch
Space Telescope Science Institute
Baltimore, Maryland, USA
|
|
From: Benjamin R. <ben...@ou...> - 2010-05-20 14:50:41
|
Ok, good, I just wanted to do a sanity check.
On Thu, May 20, 2010 at 9:21 AM, Michael Droettboom <md...@st...> wrote:
> In this case, yes. The assumption of these (private) functions is that
> x will be non-negative. The only case where we need to worry about log
> raising an exception is with exactly 0.
>
> Mike
>
> On 05/20/2010 10:08 AM, Benjamin Root wrote:
> > Do we really want to depend on a floating point equality?
> >
> > Ben Root
> >
> > On Thu, May 20, 2010 at 9:02 AM, Michael Droettboom<md...@st...>
> wrote:
> >
> >
> >> Yep. That's a bug. Here's a patch to fix it:
> >>
> >> ndex: lib/matplotlib/ticker.py
> >> ===================================================================
> >> --- lib/matplotlib/ticker.py (revision 8323)
> >> +++ lib/matplotlib/ticker.py (working copy)
> >> @@ -1178,16 +1178,21 @@
> >>
> >> def decade_down(x, base=10):
> >> 'floor x to the nearest lower decade'
> >> -
> >> + if x == 0.0:
> >> + return -base
> >> lx = math.floor(math.log(x)/math.log(base))
> >> return base**lx
> >>
> >> def decade_up(x, base=10):
> >> 'ceil x to the nearest higher decade'
> >> + if x == 0.0:
> >> + return base
> >> lx = math.ceil(math.log(x)/math.log(base))
> >> return base**lx
> >>
> >> def is_decade(x,base=10):
> >> + if x == 0.0:
> >> + return True
> >> lx = math.log(x)/math.log(base)
> >> return lx==int(lx)
> >>
> >> Mike
> >>
> >> On 05/20/2010 09:43 AM, Christer wrote:
> >>
> >>> Thank you for the help, I never knew what the symlog flag did actually.
> >>>
> >>> However, there is still a slight problem:
> >>>
> >>> =====================================================
> >>> x = array([0,1,2,4,6,9,12,24])
> >>> y = array([1000000, 500000, 100000, 100, 5, 1, 1, 1])
> >>> subplot(111)
> >>> plot(x, y)
> >>> yscale('symlog')
> >>> xscale=('linear')
> >>> ylim(-1,10000000)
> >>> show()
> >>> =====================================================
> >>>
> >>> The plot looks exactly like I want it, the problem is when I change
> >>> the "1"'s to "0"'s in the y-array, then I get a:
> >>>
> >>> File "C:\Python26\lib\site-packages\matplotlib\ticker.py", line 1029,
> >>> in is_decade
> >>> lx = math.log(x)/math.log(base)
> >>> ValueError: math domain error
> >>>
> >>> I suppose that means somewhere a log(0) is attempted. This kind of
> >>> defeats the purpose...
> >>>
> >>> /C
> >>>
> >>> Quoting Eric Firing<ef...@ha...>:
> >>>
> >>>
> >>>
> >>>> On 05/19/2010 10:28 AM, Benjamin Root wrote:
> >>>>
> >>>>
> >>>>> Maybe I am misunderstanding your problem, but you can select
> >>>>>
> >>>>>
> >>> 'semilog'
> >>>
> >>>
> >>>>> for the x/yscale parameter.
> >>>>>
> >>>>>
> >>>> You mean "symlog".
> >>>>
> >>>> See
> >>>>
> >>>>
> >>>>
> >>>
> >>
> http://matplotlib.sourceforge.net/examples/pylab_examples/symlog_demo.html
> >>
> >>>
> >>>> Although the example doesn't show it, the axis limits don't have to be
> >>>> symmetric. For example, on the top plot, you can use
> >>>>
> >>>> gca().set_xlim([0, 100])
> >>>>
> >>>> to show only the right-hand side.
> >>>>
> >>>> Eric
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>> Ben Root
> >>>>>
> >>>>> On Wed, May 19, 2010 at 7:03 AM, Christer Malmberg
> >>>>> <Chr...@st...
> >>>>> <mailto:Chr...@st...>> wrote:
> >>>>>
> >>>>> Hi,
> >>>>>
> >>>>> my problem is that I need a graph with a discontinous y-axis.
> Let
> >>>>>
> >>>>>
> >>> me
> >>>
> >>>
> >>>>> explain the problem: in my field (microbiology) the data
> >>>>>
> >>>>>
> >>> generated
> >>>
> >>>
> >>>>> from for example growth assays have a huge range (10^0-10^9),
> >>>>>
> >>>>>
> >>> which
> >>>
> >>>
> >>>>> has to be plotted on a semilogy style plot (cell concentration
> >>>>>
> >>>>>
> >>> vs.
> >>>
> >>>
> >>>>> time). The problem is that 0 cells is a useful number to plot
> >>>>> (indicates cell concentration lower than detection limit), but
> of
> >>>>> course not possible to show in a log diagram. This is easily
> >>>>>
> >>>>>
> >>> solved on
> >>>
> >>>
> >>>>> old-style logarithmic graph paper; since the data will be
> either
> >>>>>
> >>>>>
> >>> 0, or
> >>>
> >>>
> >>>>> >1 it is customary just to draw a zero x-axis at 10^-1 on the
> >>>>>
> >>>>>
> >>> paper
> >>>
> >>>
> >>>>> and that's that. On the computer, this is extremely hard. Most
> >>>>>
> >>>>>
> >>> people
> >>>
> >>>
> >>>>> I know resort to various tricks in Excel, such as entering a
> >>>>>
> >>>>>
> >>> small
> >>>
> >>>
> >>>>> number (0.001 etc) and starting the y-axis range from 10^1 to
> >>>>>
> >>>>>
> >>> hide the
> >>>
> >>>
> >>>>> problem. This makes excel draw a line, instead of leaving out
> the
> >>>>>
> >>>>>
> >>> dot
> >>>
> >>>
> >>>>> and line entirely. The part of the curve below the x-axis is
> then
> >>>>> manually cut off in a suitable image editor. Needless to say,
> >>>>>
> >>>>>
> >>> this is
> >>>
> >>>
> >>>>> extremely kludgy. Even professional graphing packages like
> >>>>>
> >>>>>
> >>> Graphpad
> >>>
> >>>
> >>>>> Prism resort to similar kludges (re-define 0 values to 0.1,
> >>>>>
> >>>>>
> >>> change the
> >>>
> >>>
> >>>>> y-axis tick label to "0" etc.) This problem of course exists in
> >>>>>
> >>>>>
> >>> other
> >>>
> >>>
> >>>>> fields, while investigating a solution I found a guy who worked
> >>>>>
> >>>>>
> >>> with
> >>>
> >>>
> >>>>> aerosol contamination in clean rooms, and he needed to plot
> >>>>>
> >>>>>
> >>> values
> >>>
> >>>
> >>>>> logarithmically, at the same time as showing detector noise
> >>>>>
> >>>>>
> >>> around
> >>>
> >>>
> >>>>> 1-10 particles. He solved it by the same trick I would like to
> do
> >>>>>
> >>>>>
> >>> in
> >>>
> >>>
> >>>>> Matplotlib, namely plotting a standard semilogy plot but with
> the
> >>>>> 10^-1 to 10^0 decade being replaced by a 0-1 linear axis on the
> >>>>>
> >>>>>
> >>> same
> >>>
> >>>
> >>>>> side.
> >>>>>
> >>>>> The guy in this post has the same problem and a useful example:
> >>>>> http://ubuntuforums.org/showthread.php?t=394851
> >>>>>
> >>>>> His partial solution is quite bad though, and I just got stuck
> >>>>>
> >>>>>
> >>> while
> >>>
> >>>
> >>>>> trying to improve it. I looked around the gallery for useful
> >>>>>
> >>>>>
> >>> examples,
> >>>
> >>>
> >>>>> and the closest I could find is the twinx/twiny function, but I
> >>>>>
> >>>>>
> >>> didn't
> >>>
> >>>
> >>>>> manage a plot that put one data curve across both axes.
> >>>>>
> >>>>> This code gives an image that maybe explains what I'm trying to
> >>>>>
> >>>>>
> >>> do:
> >>>
> >>>
> >>>>> =======================================
> >>>>> t = array([0,1,2,4,6,9,12,24])
> >>>>> y = array([1000000, 500000, 100000, 100, 5, 1, 0, 0])
> >>>>> subplot(111, xscale="linear", yscale="log")
> >>>>> errorbar(x, y, yerr=0.4*y)
> >>>>> linbit = axes([0.125, 0.1, 0.775, 0.1],frameon=False)
> >>>>> linbit.xaxis.set_visible(False)
> >>>>> for tl in linbit.get_yticklabels():
> >>>>> tl.set_color('r')
> >>>>> show()
> >>>>> =======================================
> >>>>>
> >>>>> (the y=0 points should be plotted and connected to the line in
> >>>>>
> >>>>>
> >>> the
> >>>
> >>>
> >>>>> log part)
> >>>>>
> >>>>> Is this possible to do in matplotlib? Could someone give me a
> >>>>>
> >>>>>
> >>> pointer
> >>>
> >>>
> >>>>> on how to go on?
> >>>>>
> >>>>> Sorry for the long mail,
> >>>>>
> >>>>> /C
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>
> >>
> ------------------------------------------------------------------------------
> >>
> >>>
> >>>>> _______________________________________________
> >>>>> Matplotlib-users mailing list
> >>>>> Mat...@li...
> >>>>> <mailto:Mat...@li...>
> >>>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>
> >>
> ------------------------------------------------------------------------------
> >>
> >>>
> >>>>>
> >>>>>
> >>>>> _______________________________________________
> >>>>> Matplotlib-users mailing list
> >>>>> Mat...@li...
> >>>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
> >>>>>
> >>>>>
> >>>>
> >>>>
> >>>>
> >>>
> >>
> ------------------------------------------------------------------------------
> >>
> >>>
> >>>> _______________________________________________
> >>>> Matplotlib-users mailing list
> >>>> Mat...@li...
> >>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
> >>>>
> >>>>
> >>>>
> >>>
> >>>
> >>>
> >>
> ------------------------------------------------------------------------------
> >>
> >>> _______________________________________________
> >>> Matplotlib-users mailing list
> >>> Mat...@li...
> >>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
> >>>
> >>>
> >>
> >> --
> >> Michael Droettboom
> >> Science Software Branch
> >> Space Telescope Science Institute
> >> Baltimore, Maryland, USA
> >>
> >>
> >>
> >>
> ------------------------------------------------------------------------------
> >>
> >> _______________________________________________
> >> Matplotlib-users mailing list
> >> Mat...@li...
> >> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
> >>
> >>
> >
>
>
> --
> Michael Droettboom
> Science Software Branch
> Space Telescope Science Institute
> Baltimore, Maryland, USA
>
>
>
> ------------------------------------------------------------------------------
>
> _______________________________________________
> Matplotlib-users mailing list
> Mat...@li...
> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>
|