oczkoisse
oczkoisse

Reputation: 1642

How to make xticks evenly spaced despite their value?

I am trying to generate a plot with x-axis being a geometric sequence while the y axis is a number between 0.0 and 1.0. My code looks like this:

form matplotlib import pyplot as plt
plt.xticks(X)
plt.plot(X,Y)
plt.show()

which generates a plot like this:

My plot

As you can see, I am explicitly setting the x-axis ticks to the ones belonging to the geometric sequence.

My question:Is it possible to make x-ticks evenly spaced despite their value, as the initial terms of the sequence are small, and crowded together. Kind of like logarithmic scale, which would be ideal if dealing with powers of a base, but not for a geometric sequence, I think, as is the case here.

Upvotes: 35

Views: 33935

Answers (5)

GERMAN RODRIGUEZ
GERMAN RODRIGUEZ

Reputation: 515

enter image description here

In case of using Pandas Dataframe:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

n = 12
 df = pd.DataFrame(dict(
    X=2**np.arange(n),
    Y=np.random.randint(1, 9, size=n),
    )).set_index('X')
# index is reset in order to use as xticks
df.reset_index(inplace=True)
fig = plt.figure()
ax1 = plt.subplot(111)
df['Y'].plot(kind='bar', ax=ax1, figsize=(7, 7), use_index=True)
# set_ticklabels used to place original indexes
ax1.xaxis.set_ticklabels(df['X'])

Upvotes: 1

diogo
diogo

Reputation: 771

convert int to str:

X = list(map(str, X))
plt.xticks(X)
plt.plot(X,Y)
plt.show()

Upvotes: -1

Antiez
Antiez

Reputation: 957

Seaborn has a bunch of categorical plot handling natively this kind of task.
Such as pointplot:

sns.pointplot(x="x", y="y", data=df, ax=ax)

Exemple

fig, [ax1, ax2] = plt.subplots(2, figsize=(7,7))

sns.lineplot(data=df, x="x", y="y", ax=ax1) #relational plot
sns.pointplot(data=df, x="x", y="y", ax=ax2) #categorical plot

output

Upvotes: 1

RedPers
RedPers

Reputation: 121

I had the same problem and spent several hours trying to find something appropriate. But it appears to be really easy and you do not need to make any parameterization or play with some x-ticks positions, etc.

The only thing you need to do is just to plot your x-values as str, not int: plot(x.astype('str'), y)

By modifying the code from the previous answer you will get:

n = 12
a = np.arange(n)
x = 2**a
y = np.random.rand(n)

fig = plt.figure(1, figsize=(7,7))
ax1  = fig.add_subplot(211)
ax2  = fig.add_subplot(212)

ax1.plot(x,y)
ax1.xaxis.set_ticks(x)

ax2.plot(x.astype('str'), y)

Result

Upvotes: 12

Alejandro
Alejandro

Reputation: 3412

You can do it by plotting your variable as a function of the "natural" variable that parametrizes your curve. For example:

n = 12
a = np.arange(n)
x = 2**a
y = np.random.rand(n)

fig = plt.figure(1, figsize=(7,7))
ax1  = fig.add_subplot(211)
ax2  = fig.add_subplot(212)

ax1.plot(x,y)
ax1.xaxis.set_ticks(x)

ax2.plot(a, y) #we plot y as a function of a, which parametrizes x
ax2.xaxis.set_ticks(a) #set the ticks to be a
ax2.xaxis.set_ticklabels(x) # change the ticks' names to x

which produces:

enter image description here

Upvotes: 32

Related Questions