linearized log axis

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

Maybe I am misunderstanding your problem, but you can select ‘semilog’ for the x/yscale parameter.

Ben Root

···

On Wed, May 19, 2010 at 7:03 AM, Christer Malmberg <Christer.Malmberg.0653@…3109…> 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

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users

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

···

On 05/19/2010 10:28 AM, Benjamin Root wrote:

Ben Root

On Wed, May 19, 2010 at 7:03 AM, Christer Malmberg > <Christer.Malmberg.0653@...3109... > <mailto:Christer.Malmberg.0653@…3109…>> 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:
    plotting with mixed logarithmic/linear scales

    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
    Matplotlib-users@lists.sourceforge.net
    <mailto:Matplotlib-users@lists.sourceforge.net>
    matplotlib-users List Signup and Options

------------------------------------------------------------------------------

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options