1

I am using matplotlib and I want to plot a graph in which the negative part of y axis has large numbers while the positive part has smaller values and the positive part is more valuable to show. So I prefer to draw the negative part of y axis in logarithmic scale and positive part in linear(normal) scale. Here I show whole the plot with log scale and this is my code:

    plt.plot(time_stamps,objs,'-rD', markevery=markers_on )
    markers_on=  list(i for i in range(len(upper_bound)))
    plt.plot(time_stamps,upper_bound,'-bD', markevery=markers_on )
    markers_on=  list(i for i in range(len(best_P_list)))
    plt.plot(exce_time_list,best_P_list,'-gD', markevery=markers_on)
    plt.xlabel("x", fontsize=10)
    plt.ylabel("y ", fontsize=10)
    plt.yscale('symlog')
    plt.show() 

enter image description here

How can I show positive part of y axis in linear scale?

hamta
  • 75
  • 2
  • 10
  • You can always use funcscale https://matplotlib.org/stable/api/scale_api.html#matplotlib.scale.FuncScale but if you want alternating labels you’ll have to either hard code them or make a custom formatter – Jody Klymak May 15 '22 at 15:33

1 Answers1

1

I completely reworked my answer because I found this SO answer which explains how to divide axes to behave differently.

Now, we still need to separate the different values and steps but it's much clearer.

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np


vals = np.array([-1e10, -1e7, 1e3, 1e2, -1e8, -1e1, 1e3, 500])
steps = np.array([0, 5, 1, 4, 9, 20, 7, 15])


def plot_diff_scales(vals, steps):
    fig, ax = plt.subplots()
    ax.plot(steps[vals >= 0], vals[vals >= 0], "-gD")  # only positive values
    ax.set_yscale("linear")
    ax.spines["bottom"].set_visible(False)  # hide bottom of box
    ax.get_xaxis().set_visible(False)  # hide x-axis entirely
    ax.set_ylabel("Linear axis")
    # Dividing the axes
    divider = make_axes_locatable(ax)
    ax_log = divider.append_axes("bottom", size=2, pad=0, sharex=ax)
    # Acting on the log axis
    ax_log.set_yscale("symlog")
    ax_log.spines["top"].set_visible(False)  # hide top of box
    ax_log.plot(steps[vals < 0], vals[vals < 0], "-bD")  # only negative values
    ax_log.set_xlabel("X axis")
    ax_log.set_ylabel("Symlog axis")
    # Show delimiter
    ax.axhline(y=0, color="black", linestyle="dashed", linewidth=1)
    # Plotting proper
    fig.tight_layout()
    plt.show()


plot_diff_scales(vals, steps)

enter image description here

Nathan Furnal
  • 2,236
  • 3
  • 12
  • 25