Python Matplotlib: Set axis as increments with respect to one value
Some times when a plot is zoomed in enough the axis change so showing something like this
which means that the x value is, in this case 1.565 + the value showed in the tick.
Is there a way to set the axis ticks in this format? And once there how can I set the offset (The 1.565 in this case) and format the ticks?
python matplotlib graphing
add a comment |
Some times when a plot is zoomed in enough the axis change so showing something like this
which means that the x value is, in this case 1.565 + the value showed in the tick.
Is there a way to set the axis ticks in this format? And once there how can I set the offset (The 1.565 in this case) and format the ticks?
python matplotlib graphing
So you would start with anoffset
and alist_of_ticks
and want to show it in the way as in the picture?
– ImportanceOfBeingErnest
Nov 20 '18 at 16:03
@ImportanceOfBeingErnest yes, concretely what I want is to center the axes atpi/2
and then set the ticks at[..., pi/2 -0.02, pi/2 - 0.01, pi/2, pi/2 + 0.01, ...]
, so that it shows[..., -0.02, - 0.01, 0, 0.01, ...]
and theoffset = pi/2
– Alex
Nov 20 '18 at 16:11
add a comment |
Some times when a plot is zoomed in enough the axis change so showing something like this
which means that the x value is, in this case 1.565 + the value showed in the tick.
Is there a way to set the axis ticks in this format? And once there how can I set the offset (The 1.565 in this case) and format the ticks?
python matplotlib graphing
Some times when a plot is zoomed in enough the axis change so showing something like this
which means that the x value is, in this case 1.565 + the value showed in the tick.
Is there a way to set the axis ticks in this format? And once there how can I set the offset (The 1.565 in this case) and format the ticks?
python matplotlib graphing
python matplotlib graphing
asked Nov 20 '18 at 15:59
AlexAlex
253
253
So you would start with anoffset
and alist_of_ticks
and want to show it in the way as in the picture?
– ImportanceOfBeingErnest
Nov 20 '18 at 16:03
@ImportanceOfBeingErnest yes, concretely what I want is to center the axes atpi/2
and then set the ticks at[..., pi/2 -0.02, pi/2 - 0.01, pi/2, pi/2 + 0.01, ...]
, so that it shows[..., -0.02, - 0.01, 0, 0.01, ...]
and theoffset = pi/2
– Alex
Nov 20 '18 at 16:11
add a comment |
So you would start with anoffset
and alist_of_ticks
and want to show it in the way as in the picture?
– ImportanceOfBeingErnest
Nov 20 '18 at 16:03
@ImportanceOfBeingErnest yes, concretely what I want is to center the axes atpi/2
and then set the ticks at[..., pi/2 -0.02, pi/2 - 0.01, pi/2, pi/2 + 0.01, ...]
, so that it shows[..., -0.02, - 0.01, 0, 0.01, ...]
and theoffset = pi/2
– Alex
Nov 20 '18 at 16:11
So you would start with an
offset
and a list_of_ticks
and want to show it in the way as in the picture?– ImportanceOfBeingErnest
Nov 20 '18 at 16:03
So you would start with an
offset
and a list_of_ticks
and want to show it in the way as in the picture?– ImportanceOfBeingErnest
Nov 20 '18 at 16:03
@ImportanceOfBeingErnest yes, concretely what I want is to center the axes at
pi/2
and then set the ticks at [..., pi/2 -0.02, pi/2 - 0.01, pi/2, pi/2 + 0.01, ...]
, so that it shows [..., -0.02, - 0.01, 0, 0.01, ...]
and the offset = pi/2
– Alex
Nov 20 '18 at 16:11
@ImportanceOfBeingErnest yes, concretely what I want is to center the axes at
pi/2
and then set the ticks at [..., pi/2 -0.02, pi/2 - 0.01, pi/2, pi/2 + 0.01, ...]
, so that it shows [..., -0.02, - 0.01, 0, 0.01, ...]
and the offset = pi/2
– Alex
Nov 20 '18 at 16:11
add a comment |
1 Answer
1
active
oldest
votes
A. Manually placing the offset
I think the easiest solution is to plot x-offset
, instead of x
itself. Then just add a text field with the offset below the axes.
import numpy as np
import matplotlib.pyplot as plt
x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]
plt.plot(x - np.pi/2, y)
plt.text(1, -0.07, "$+pi / 2$", ha="right", va="top",
transform=plt.gca().transAxes)
plt.show()
B. Using a fixed formatter
Alternatively you can use a FixedFormatter
and set its offset label manually.
import numpy as np
import matplotlib.pyplot as plt
x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]
plt.plot(x, y)
xticks = np.array([-0.02, -0.01, 0, 0.01, 0.02])
plt.gca().set(xticks = xticks + np.pi/2,
xticklabels = xticks)
plt.gca().xaxis.get_major_formatter().set_offset_string("$+pi / 2$")
plt.show()
The drawback of this is that the tick positions are fixed so you loose the nice labeling when zooming.
C. Using a custom locator and formatter with a fixed offset
This is possible but utterly complicated. The solution would look similar to Set scientific notation with fixed exponent and significant digits for multiple subplots but needs to use a Locator as well.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker
class OffsetLocator(matplotlib.ticker.AutoLocator):
def __init__(self, offset=0):
self.fixed_offset = offset
matplotlib.ticker.AutoLocator.__init__(self)
def tick_values(self, vmin, vmax):
v = np.array([vmin,vmax])-self.fixed_offset
ticks = matplotlib.ticker.AutoLocator.tick_values(self, *v)
return ticks + self.fixed_offset
class OffsetFormatter(matplotlib.ticker.ScalarFormatter):
def __init__(self, offset=0, offsettext = None, mathText=True):
self.fixed_offset = offset
self.offset_text = offsettext
matplotlib.ticker.ScalarFormatter.__init__(self,useOffset=offset,
useMathText=mathText)
def _set_orderOfMagnitude(self, nothing):
self.orderOfMagnitude = 0
def _compute_offset(self):
return self.fixed_offset
def get_offset(self):
return self.offset_text or matplotlib.ticker.ScalarFormatter.get_offset(self)
x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]
plt.plot(x, y)
plt.gca().xaxis.set_major_locator(OffsetLocator(np.pi/2))
plt.gca().xaxis.set_major_formatter(OffsetFormatter(np.pi/2, offsettext="$+pi / 2$"))
plt.show()
The result looks similar to the above, but behaves completely natural like in all other cases where some offset is used. One will probably observe the differences only when playing with figure size, zooming and panning etc.
I updated the answer with the completely general solution now. Would be interesting to know which of those you decide to go with.
– ImportanceOfBeingErnest
Nov 21 '18 at 0:28
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53396891%2fpython-matplotlib-set-axis-as-increments-with-respect-to-one-value%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
A. Manually placing the offset
I think the easiest solution is to plot x-offset
, instead of x
itself. Then just add a text field with the offset below the axes.
import numpy as np
import matplotlib.pyplot as plt
x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]
plt.plot(x - np.pi/2, y)
plt.text(1, -0.07, "$+pi / 2$", ha="right", va="top",
transform=plt.gca().transAxes)
plt.show()
B. Using a fixed formatter
Alternatively you can use a FixedFormatter
and set its offset label manually.
import numpy as np
import matplotlib.pyplot as plt
x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]
plt.plot(x, y)
xticks = np.array([-0.02, -0.01, 0, 0.01, 0.02])
plt.gca().set(xticks = xticks + np.pi/2,
xticklabels = xticks)
plt.gca().xaxis.get_major_formatter().set_offset_string("$+pi / 2$")
plt.show()
The drawback of this is that the tick positions are fixed so you loose the nice labeling when zooming.
C. Using a custom locator and formatter with a fixed offset
This is possible but utterly complicated. The solution would look similar to Set scientific notation with fixed exponent and significant digits for multiple subplots but needs to use a Locator as well.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker
class OffsetLocator(matplotlib.ticker.AutoLocator):
def __init__(self, offset=0):
self.fixed_offset = offset
matplotlib.ticker.AutoLocator.__init__(self)
def tick_values(self, vmin, vmax):
v = np.array([vmin,vmax])-self.fixed_offset
ticks = matplotlib.ticker.AutoLocator.tick_values(self, *v)
return ticks + self.fixed_offset
class OffsetFormatter(matplotlib.ticker.ScalarFormatter):
def __init__(self, offset=0, offsettext = None, mathText=True):
self.fixed_offset = offset
self.offset_text = offsettext
matplotlib.ticker.ScalarFormatter.__init__(self,useOffset=offset,
useMathText=mathText)
def _set_orderOfMagnitude(self, nothing):
self.orderOfMagnitude = 0
def _compute_offset(self):
return self.fixed_offset
def get_offset(self):
return self.offset_text or matplotlib.ticker.ScalarFormatter.get_offset(self)
x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]
plt.plot(x, y)
plt.gca().xaxis.set_major_locator(OffsetLocator(np.pi/2))
plt.gca().xaxis.set_major_formatter(OffsetFormatter(np.pi/2, offsettext="$+pi / 2$"))
plt.show()
The result looks similar to the above, but behaves completely natural like in all other cases where some offset is used. One will probably observe the differences only when playing with figure size, zooming and panning etc.
I updated the answer with the completely general solution now. Would be interesting to know which of those you decide to go with.
– ImportanceOfBeingErnest
Nov 21 '18 at 0:28
add a comment |
A. Manually placing the offset
I think the easiest solution is to plot x-offset
, instead of x
itself. Then just add a text field with the offset below the axes.
import numpy as np
import matplotlib.pyplot as plt
x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]
plt.plot(x - np.pi/2, y)
plt.text(1, -0.07, "$+pi / 2$", ha="right", va="top",
transform=plt.gca().transAxes)
plt.show()
B. Using a fixed formatter
Alternatively you can use a FixedFormatter
and set its offset label manually.
import numpy as np
import matplotlib.pyplot as plt
x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]
plt.plot(x, y)
xticks = np.array([-0.02, -0.01, 0, 0.01, 0.02])
plt.gca().set(xticks = xticks + np.pi/2,
xticklabels = xticks)
plt.gca().xaxis.get_major_formatter().set_offset_string("$+pi / 2$")
plt.show()
The drawback of this is that the tick positions are fixed so you loose the nice labeling when zooming.
C. Using a custom locator and formatter with a fixed offset
This is possible but utterly complicated. The solution would look similar to Set scientific notation with fixed exponent and significant digits for multiple subplots but needs to use a Locator as well.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker
class OffsetLocator(matplotlib.ticker.AutoLocator):
def __init__(self, offset=0):
self.fixed_offset = offset
matplotlib.ticker.AutoLocator.__init__(self)
def tick_values(self, vmin, vmax):
v = np.array([vmin,vmax])-self.fixed_offset
ticks = matplotlib.ticker.AutoLocator.tick_values(self, *v)
return ticks + self.fixed_offset
class OffsetFormatter(matplotlib.ticker.ScalarFormatter):
def __init__(self, offset=0, offsettext = None, mathText=True):
self.fixed_offset = offset
self.offset_text = offsettext
matplotlib.ticker.ScalarFormatter.__init__(self,useOffset=offset,
useMathText=mathText)
def _set_orderOfMagnitude(self, nothing):
self.orderOfMagnitude = 0
def _compute_offset(self):
return self.fixed_offset
def get_offset(self):
return self.offset_text or matplotlib.ticker.ScalarFormatter.get_offset(self)
x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]
plt.plot(x, y)
plt.gca().xaxis.set_major_locator(OffsetLocator(np.pi/2))
plt.gca().xaxis.set_major_formatter(OffsetFormatter(np.pi/2, offsettext="$+pi / 2$"))
plt.show()
The result looks similar to the above, but behaves completely natural like in all other cases where some offset is used. One will probably observe the differences only when playing with figure size, zooming and panning etc.
I updated the answer with the completely general solution now. Would be interesting to know which of those you decide to go with.
– ImportanceOfBeingErnest
Nov 21 '18 at 0:28
add a comment |
A. Manually placing the offset
I think the easiest solution is to plot x-offset
, instead of x
itself. Then just add a text field with the offset below the axes.
import numpy as np
import matplotlib.pyplot as plt
x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]
plt.plot(x - np.pi/2, y)
plt.text(1, -0.07, "$+pi / 2$", ha="right", va="top",
transform=plt.gca().transAxes)
plt.show()
B. Using a fixed formatter
Alternatively you can use a FixedFormatter
and set its offset label manually.
import numpy as np
import matplotlib.pyplot as plt
x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]
plt.plot(x, y)
xticks = np.array([-0.02, -0.01, 0, 0.01, 0.02])
plt.gca().set(xticks = xticks + np.pi/2,
xticklabels = xticks)
plt.gca().xaxis.get_major_formatter().set_offset_string("$+pi / 2$")
plt.show()
The drawback of this is that the tick positions are fixed so you loose the nice labeling when zooming.
C. Using a custom locator and formatter with a fixed offset
This is possible but utterly complicated. The solution would look similar to Set scientific notation with fixed exponent and significant digits for multiple subplots but needs to use a Locator as well.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker
class OffsetLocator(matplotlib.ticker.AutoLocator):
def __init__(self, offset=0):
self.fixed_offset = offset
matplotlib.ticker.AutoLocator.__init__(self)
def tick_values(self, vmin, vmax):
v = np.array([vmin,vmax])-self.fixed_offset
ticks = matplotlib.ticker.AutoLocator.tick_values(self, *v)
return ticks + self.fixed_offset
class OffsetFormatter(matplotlib.ticker.ScalarFormatter):
def __init__(self, offset=0, offsettext = None, mathText=True):
self.fixed_offset = offset
self.offset_text = offsettext
matplotlib.ticker.ScalarFormatter.__init__(self,useOffset=offset,
useMathText=mathText)
def _set_orderOfMagnitude(self, nothing):
self.orderOfMagnitude = 0
def _compute_offset(self):
return self.fixed_offset
def get_offset(self):
return self.offset_text or matplotlib.ticker.ScalarFormatter.get_offset(self)
x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]
plt.plot(x, y)
plt.gca().xaxis.set_major_locator(OffsetLocator(np.pi/2))
plt.gca().xaxis.set_major_formatter(OffsetFormatter(np.pi/2, offsettext="$+pi / 2$"))
plt.show()
The result looks similar to the above, but behaves completely natural like in all other cases where some offset is used. One will probably observe the differences only when playing with figure size, zooming and panning etc.
A. Manually placing the offset
I think the easiest solution is to plot x-offset
, instead of x
itself. Then just add a text field with the offset below the axes.
import numpy as np
import matplotlib.pyplot as plt
x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]
plt.plot(x - np.pi/2, y)
plt.text(1, -0.07, "$+pi / 2$", ha="right", va="top",
transform=plt.gca().transAxes)
plt.show()
B. Using a fixed formatter
Alternatively you can use a FixedFormatter
and set its offset label manually.
import numpy as np
import matplotlib.pyplot as plt
x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]
plt.plot(x, y)
xticks = np.array([-0.02, -0.01, 0, 0.01, 0.02])
plt.gca().set(xticks = xticks + np.pi/2,
xticklabels = xticks)
plt.gca().xaxis.get_major_formatter().set_offset_string("$+pi / 2$")
plt.show()
The drawback of this is that the tick positions are fixed so you loose the nice labeling when zooming.
C. Using a custom locator and formatter with a fixed offset
This is possible but utterly complicated. The solution would look similar to Set scientific notation with fixed exponent and significant digits for multiple subplots but needs to use a Locator as well.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker
class OffsetLocator(matplotlib.ticker.AutoLocator):
def __init__(self, offset=0):
self.fixed_offset = offset
matplotlib.ticker.AutoLocator.__init__(self)
def tick_values(self, vmin, vmax):
v = np.array([vmin,vmax])-self.fixed_offset
ticks = matplotlib.ticker.AutoLocator.tick_values(self, *v)
return ticks + self.fixed_offset
class OffsetFormatter(matplotlib.ticker.ScalarFormatter):
def __init__(self, offset=0, offsettext = None, mathText=True):
self.fixed_offset = offset
self.offset_text = offsettext
matplotlib.ticker.ScalarFormatter.__init__(self,useOffset=offset,
useMathText=mathText)
def _set_orderOfMagnitude(self, nothing):
self.orderOfMagnitude = 0
def _compute_offset(self):
return self.fixed_offset
def get_offset(self):
return self.offset_text or matplotlib.ticker.ScalarFormatter.get_offset(self)
x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]
plt.plot(x, y)
plt.gca().xaxis.set_major_locator(OffsetLocator(np.pi/2))
plt.gca().xaxis.set_major_formatter(OffsetFormatter(np.pi/2, offsettext="$+pi / 2$"))
plt.show()
The result looks similar to the above, but behaves completely natural like in all other cases where some offset is used. One will probably observe the differences only when playing with figure size, zooming and panning etc.
edited Nov 21 '18 at 0:26
answered Nov 20 '18 at 16:56
ImportanceOfBeingErnestImportanceOfBeingErnest
135k13150225
135k13150225
I updated the answer with the completely general solution now. Would be interesting to know which of those you decide to go with.
– ImportanceOfBeingErnest
Nov 21 '18 at 0:28
add a comment |
I updated the answer with the completely general solution now. Would be interesting to know which of those you decide to go with.
– ImportanceOfBeingErnest
Nov 21 '18 at 0:28
I updated the answer with the completely general solution now. Would be interesting to know which of those you decide to go with.
– ImportanceOfBeingErnest
Nov 21 '18 at 0:28
I updated the answer with the completely general solution now. Would be interesting to know which of those you decide to go with.
– ImportanceOfBeingErnest
Nov 21 '18 at 0:28
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53396891%2fpython-matplotlib-set-axis-as-increments-with-respect-to-one-value%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
So you would start with an
offset
and alist_of_ticks
and want to show it in the way as in the picture?– ImportanceOfBeingErnest
Nov 20 '18 at 16:03
@ImportanceOfBeingErnest yes, concretely what I want is to center the axes at
pi/2
and then set the ticks at[..., pi/2 -0.02, pi/2 - 0.01, pi/2, pi/2 + 0.01, ...]
, so that it shows[..., -0.02, - 0.01, 0, 0.01, ...]
and theoffset = pi/2
– Alex
Nov 20 '18 at 16:11