|
From: Mario M. <me...@me...> - 2010-01-20 13:27:36
|
Hi,
it's probably a rather simple problem. Unfortunately I'm unable to solve it.
The following code example describes my problem:
import numpy as np
from matplotlib import pyplot,mpl
x = np.arange(10)
y = np.arange(25)
z = np.floor(10*np.random.random((25,10)))
pyplot.contourf(x,y,z)
cb = pyplot.colorbar(format=r"%2.1f")
for j in cb.ax.get_yticklabels():
j.set_text('bla')
pyplot.show()
Now I'd like to change the smallest label of the colorbar to 0.0 (without the minus sign). But any attemps to change the ticklabels of the colorbar fail:
cb = pyplot.colorbar(format=r"%2.1f")
for j in cb.ax.get_yticklabels():
j.set_text('bla')
pyplot.show()
Doesn't do anything. Evenmore I don't understand why
for j in cb.ax.get_yticklabels():
print str(j)
results in
Text(0,0,'')
Text(0,0,'')
Text(0,0,'')
Text(0,0,'')
Text(0,0,'')
Text(0,0,'')
Text(0,0,'')
Thanks in advance
Mario Mech
|
|
From: Scott S. <sco...@gm...> - 2010-01-20 13:55:35
|
>2010/1/20 Mario Mech <me...@me...>:
> cb = pyplot.colorbar(format=r"%2.1f")
> for j in cb.ax.get_yticklabels():
> j.set_text('bla')
> pyplot.show()
>
> Doesn't do anything.
It looks like cb.ax.get_yticklabels() returns a list of copies of the
Text objects. Since you are only changing the copies it has no effect
on your figure.
You'll need to use cb.ax.set_yticklabels() and pass a list of strings
to use as tick labels. See
http://matplotlib.sourceforge.net/examples/pylab_examples/colorbar_tick_labelling_demo.html
for an example.
Cheers,
Scott
|
|
From: Mario M. <me...@me...> - 2010-01-20 14:17:27
|
On 20.01.2010 14:55, Scott Sinclair wrote:
>> 2010/1/20 Mario Mech<me...@me...>:
>> cb = pyplot.colorbar(format=r"%2.1f")
>> for j in cb.ax.get_yticklabels():
>> j.set_text('bla')
>> pyplot.show()
>>
>> Doesn't do anything.
>
> It looks like cb.ax.get_yticklabels() returns a list of copies of the
> Text objects. Since you are only changing the copies it has no effect
> on your figure.
> You'll need to use cb.ax.set_yticklabels() and pass a list of strings
> to use as tick labels. See
> http://matplotlib.sourceforge.net/examples/pylab_examples/colorbar_tick_labelling_demo.html
> for an example.
>
> Cheers,
> Scott
Ok, something like
cl = cb.ax.get_yticklabels()
cl[0].set_text('bla')
cb.ax.set_yticklabels([elem.get_text() for elem in cl])
would work for the horizontal colorbars and y replaced by x. But
cl = cb.ax.get_yticklabels()
results in a list of Text objects like Text(0,0,''). So my problem is more to get the TickLabels for vertical colorbars.
Cheers
Mario
--
Dr. Mario Mech
Institute for Geophysics and Meteorology
University of Cologne
Zuelpicher Str. 49a
50674 Cologne
Germany
t: +49 (0)221 - 470 - 1776
f: +49 (0)221 - 470 - 5198
e: me...@me...
w: http://www.meteo.uni-koeln.de/~mmech/
|
|
From: Scott S. <sco...@gm...> - 2010-01-20 14:43:17
|
>2010/1/20 Mario Mech <me...@me...>:
> Ok, something like
>
> cl = cb.ax.get_yticklabels()
> cl[0].set_text('bla')
> cb.ax.set_yticklabels([elem.get_text() for elem in cl])
This works for me.
> But
>
> cl = cb.ax.get_yticklabels()
>
> results in a list of Text objects like Text(0,0,'').
I have no idea what's happening then. I see:
for l in cl:
print(l)
Text(0,0,'bla')
Text(0.166667,0.166667,'1.5')
Text(0.333333,0.333333,'3.0')
Text(0.5,0.5,'4.5')
Text(0.666667,0.666667,'6.0')
Text(0.833333,0.833333,'7.5')
Text(1,1,'9.0')
Cheers,
Scott
|
|
From: Mario M. <me...@me...> - 2010-01-20 15:18:19
|
> This works for me. > >> But >> >> cl = cb.ax.get_yticklabels() >> >> results in a list of Text objects like Text(0,0,''). > > I have no idea what's happening then. I see: > > for l in cl: > print(l) > > Text(0,0,'bla') > Text(0.166667,0.166667,'1.5') > Text(0.333333,0.333333,'3.0') > Text(0.5,0.5,'4.5') > Text(0.666667,0.666667,'6.0') > Text(0.833333,0.833333,'7.5') > Text(1,1,'9.0') > > Cheers, > Scott Has it anything to do with my matplotlib version (0.99.0) and python (2.6.4) on ubuntu karmic? following code: #------ import numpy as np from matplotlib import pyplot,mpl x = np.arange(10) y = np.arange(25) z = np.floor(10*np.random.random((25,10))) pyplot.contourf(x,y,z) cb = pyplot.colorbar() for j in cb.ax.get_yticklabels(): print(j) #---- results in: Text(0,0,'') Text(0,0,'') Text(0,0,'') Text(0,0,'') Text(0,0,'') Text(0,0,'') Text(0,0,'') That's not what i expected and makes it hard to change single ticklabels. Cheers, Mario -- Dr. Mario Mech Institute for Geophysics and Meteorology University of Cologne Zuelpicher Str. 49a 50674 Cologne Germany t: +49 (0)221 - 470 - 1776 f: +49 (0)221 - 470 - 5198 e: me...@me... w: http://www.meteo.uni-koeln.de/~mmech/ |
|
From: Sebastian B. <web...@th...> - 2010-01-20 16:15:59
Attachments:
signature.asc
|
Mario Mech wrote:
> ...
> #------
> import numpy as np
> from matplotlib import pyplot,mpl
>
> x = np.arange(10)
> y = np.arange(25)
> z = np.floor(10*np.random.random((25,10)))
>
> pyplot.contourf(x,y,z)
>
> cb = pyplot.colorbar()
>
> for j in cb.ax.get_yticklabels():
> print(j)
> #----
>
> results in:
>
> Text(0,0,'')
> ...
I think you have to pyplot.show() or pyplot.savefig("deleteme.ps") in
order to have the ticklabels populated.
best,
sebastian.
|
|
From: Jae-Joon L. <lee...@gm...> - 2010-01-20 17:06:29
|
On Wed, Jan 20, 2010 at 9:17 AM, Mario Mech <me...@me...> wrote:
> cl = cb.ax.get_yticklabels()
>
> results in a list of Text objects like Text(0,0,''). So my problem is more to get the TickLabels for vertical colorbars.
>
Can you elaborate why you need to do this?
This is a general behavior of Axes in matplotlib (i.e., not colorbar
specific). There are things that are evaluated later when the figure
gets drawn.
You may use iter_ticks method if it fits your need.
for j, p, l in cb.ax.yaxis.iter_ticks():
print l
To change the ticklabels of colorbar, they need to be set when the
colorbar is created, as Scott suggested. This is a limitation of the
current colobar implementation. Changing ticklabels (or locations)
after colorbar is created is quite tricky.
Regards,
-JJ
|
|
From: Mario M. <me...@me...> - 2010-01-20 17:12:22
|
> Can you elaborate why you need to do this? As you can see in my example: #------ import numpy as np from matplotlib import pyplot,mpl x = np.arange(10) y = np.arange(25) z = np.floor(10*np.random.random((25,10))) pyplot.contourf(x,y,z) cb = pyplot.colorbar() pyplot.show() #------ the smallest value (0.0) is labeled with "-0.0". I just want to get rid of the minus sign. Cheers Mario > This is a general behavior of Axes in matplotlib (i.e., not colorbar > specific). There are things that are evaluated later when the figure > gets drawn. > You may use iter_ticks method if it fits your need. > > for j, p, l in cb.ax.yaxis.iter_ticks(): > print l > > To change the ticklabels of colorbar, they need to be set when the > colorbar is created, as Scott suggested. This is a limitation of the > current colobar implementation. Changing ticklabels (or locations) > after colorbar is created is quite tricky. > > Regards, > > -JJ -- Dr. Mario Mech Institute for Geophysics and Meteorology University of Cologne Zuelpicher Str. 49a 50674 Cologne Germany t: +49 (0)221 - 470 - 1776 f: +49 (0)221 - 470 - 5198 e: me...@me... w: http://www.meteo.uni-koeln.de/~mmech/ |
|
From: Jae-Joon L. <lee...@gm...> - 2010-01-20 18:20:49
|
On Wed, Jan 20, 2010 at 12:12 PM, Mario Mech <me...@me...> wrote:
> the smallest value (0.0) is labeled with "-0.0". I just want to get rid of the minus sign.
>
This is because the actual value is "-9.00000000e-06" (this inherits
from the levels of contour).
While I think we're fixing a wrong problem (the contour routine need
to be fixed in my view), here is a workaround you may use.
-JJ
import numpy as np
from matplotlib import pyplot,mpl
x = np.arange(10)
y = np.arange(25)
z = np.floor(10*np.random.random((25,10)))
cntr = pyplot.contourf(x,y,z)
cb = pyplot.colorbar(format=r"%2.1f")
ticklabel_seq = cb.ax.yaxis.major.formatter.seq
try:
indx = ticklabel_seq.index("-0.0")
ticklabel_seq[indx]="0.0"
except ValueError:
pass
pyplot.show()
|
|
From: Eric F. <ef...@ha...> - 2010-01-20 18:36:57
|
Jae-Joon Lee wrote:
> On Wed, Jan 20, 2010 at 12:12 PM, Mario Mech <me...@me...> wrote:
>> the smallest value (0.0) is labeled with "-0.0". I just want to get rid of the minus sign.
>>
>
> This is because the actual value is "-9.00000000e-06" (this inherits
> from the levels of contour).
> While I think we're fixing a wrong problem (the contour routine need
> to be fixed in my view), here is a workaround you may use.
Careful, that slight adjustment of the lower limit, when automatically
generated, is there for a reason (though I don't recall offhand where it
is arising and why). There may be a better way to do it--and we can try
to figure it out and implement it--but my advice in general is: don't
use automatically generated contour or contourf levels except for
exploratory, interactive work, when slight imperfections are acceptable.
Instead, figure out what levels you really want, and supply them
explicitly as one of the arguments.
Second and related advice: don't fiddle directly with tick labels except
as a *last* resort. Instead, take care in selecting tick values, and if
necessary, customize the Formatter.
The fact that a default Formatter is writing -0.0 strikes me as a bug
that should be fixed in the Formatter; but it would be good to have more
opinions about this.
Eric
>
> -JJ
>
> import numpy as np
> from matplotlib import pyplot,mpl
>
> x = np.arange(10)
> y = np.arange(25)
> z = np.floor(10*np.random.random((25,10)))
>
> cntr = pyplot.contourf(x,y,z)
>
> cb = pyplot.colorbar(format=r"%2.1f")
>
>
> ticklabel_seq = cb.ax.yaxis.major.formatter.seq
> try:
> indx = ticklabel_seq.index("-0.0")
> ticklabel_seq[indx]="0.0"
> except ValueError:
> pass
>
>
> pyplot.show()
>
> ------------------------------------------------------------------------------
> Throughout its 18-year history, RSA Conference consistently attracts the
> world's best and brightest in the field, creating opportunities for Conference
> attendees to learn about information security's most important issues through
> interactions with peers, luminaries and emerging and established companies.
> http://p.sf.net/sfu/rsaconf-dev2dev
> _______________________________________________
> Matplotlib-users mailing list
> Mat...@li...
> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
|
|
From: Jae-Joon L. <lee...@gm...> - 2010-01-20 19:07:35
|
On Wed, Jan 20, 2010 at 1:36 PM, Eric Firing <ef...@ha...> wrote: > Second and related advice: don't fiddle directly with tick labels except as > a *last* resort. Instead, take care in selecting tick values, and if > necessary, customize the Formatter. > Agreed. It was a quick hack. > The fact that a default Formatter is writing -0.0 strikes me as a bug that > should be fixed in the Formatter; but it would be good to have more opinions > about this. > This is a behavior of python and I think it makes sense. In [92]: print "%2.1f" % (-9e-6,) -0.0 Regards, -JJ |
|
From: Eric F. <ef...@ha...> - 2010-01-20 19:04:28
|
Jae-Joon Lee wrote: > On Wed, Jan 20, 2010 at 12:12 PM, Mario Mech <me...@me...> wrote: >> the smallest value (0.0) is labeled with "-0.0". I just want to get rid of the minus sign. >> > > This is because the actual value is "-9.00000000e-06" (this inherits > from the levels of contour). The reason for this fudge in contour is that contourf fills lower < z <= upper for each consecutive pair of contour levels. When the minimum value of z coincides with the lowest level, then regions with that minimum are left blank; so the lowest level is adjusted downward slightly, making the lowest contour interval include the minimum value. The fudge could be made optional via a kwarg, e.g., include_minimum=True (default) or False (to defeat the fudge). This would not help Mario, though, assuming he is happy with the present contouring, and simply wants sane labeling of the 0-tick. For that, a Formatter adjustment is the simplest solution. Eric |
|
From: Jae-Joon L. <lee...@gm...> - 2010-01-20 19:14:13
|
On Wed, Jan 20, 2010 at 2:04 PM, Eric Firing <ef...@ha...> wrote:
> The reason for this fudge in contour is that contourf fills
> lower < z <= upper
> for each consecutive pair of contour levels.
> When the minimum value of z coincides with the lowest level, then regions
> with that minimum are left blank; so the lowest level is adjusted downward
> slightly, making the lowest contour interval include the minimum value.
>
I understand levels can be adjusted for a better contouring, but I'm
not sure whether this change needs to be visible to users.
The autoleveler, initially creates following levels
[0, 1.5, 3, 4.5, 6, 7.5, 9.]
But due to the reason you described above, they become
array([ -9.00000000e-06, 1.50000000e+00, 3.00000000e+00,
4.50000000e+00, 6.00000000e+00, 7.50000000e+00,
9.00000900e+00])
And the colorbar uses the adjusted levels for labeling. But I think it
may make more sense to use the initial levels (at least for the
colorbar ticks).
Regards,
-JJ
|
|
From: Eric F. <ef...@ha...> - 2010-01-22 02:25:01
|
Jae-Joon Lee wrote: > On Wed, Jan 20, 2010 at 2:04 PM, Eric Firing <ef...@ha...> wrote: >> The reason for this fudge in contour is that contourf fills >> lower < z <= upper >> for each consecutive pair of contour levels. >> When the minimum value of z coincides with the lowest level, then regions >> with that minimum are left blank; so the lowest level is adjusted downward >> slightly, making the lowest contour interval include the minimum value. >> > > I understand levels can be adjusted for a better contouring, but I'm > not sure whether this change needs to be visible to users. > > The autoleveler, initially creates following levels > > [0, 1.5, 3, 4.5, 6, 7.5, 9.] > > But due to the reason you described above, they become > > array([ -9.00000000e-06, 1.50000000e+00, 3.00000000e+00, > 4.50000000e+00, 6.00000000e+00, 7.50000000e+00, > 9.00000900e+00]) > > And the colorbar uses the adjusted levels for labeling. But I think it > may make more sense to use the initial levels (at least for the > colorbar ticks). JJ, I changed my mind and decided you are correct in thinking the change should be made in contour.py. I now make the bottom boundary adjustment at the last possible time, and in such a way that it does not change the levels array at all. Therefore the colorbar never sees it, and the result of explicitly supplying a set of levels is identical to the case where those levels result from autoscaling. Eric > > Regards, > > -JJ |
|
From: Jae-Joon L. <lee...@gm...> - 2010-01-22 04:44:39
|
On Thu, Jan 21, 2010 at 9:24 PM, Eric Firing <ef...@ha...> wrote: > I changed my mind and decided you are correct in thinking the change should > be made in contour.py. I now make the bottom boundary adjustment at the > last possible time, and in such a way that it does not change the levels > array at all. Therefore the colorbar never sees it, and the result of > explicitly supplying a set of levels is identical to the case where those > levels result from autoscaling. > Great! Thanks~ -JJ |