Plotly colourbar legend not showing max or min value - legend

I have a plotly chart with a colourbar legend.
I'd like this to go from 0 to 100 with the ticks set every 10.
No matter how I try, the chart always starts the ticks at 10 and ends at 90. Removing my top and bottom tick.
Any thoughts on how to make these appear? the API doesn't seem particularly complete in this area.

trace = go.Heatmap( colorscale=COLORSCALE,
colorbar = dict(
tickvals = [0,10,20,30,40,50,60,70,80,90,100],
tickmode = 'array',
)
...
)
would be one way, in Python; practically the same in JS
But as #Levent pointed out, we can't tell you what you need without code.

Related

Heatmap colorbars accumulating in Matplotlib/Seaborn figures

I have a list of data frames, and I want to make heatmaps of every data frame in the list. The first heatmap comes out perfectly, but the second one has two colorbars, one much larger than the other, which distorts the figure. The third has THREE colorbars, the last one being even larger, and this continues for as many heatmaps as I make.
This seems like a bug to me, as I have no idea why it's happening. Each heatmap should be stored as a separate element in the list of heatmaps, and even if I plot them individually, instead of using a loop or list comprehension, I get the same problem.
Here is my code:
# Set the seaborn font size.
sns.set(font_scale=0.5)
# Ensure that labels are not cut off.
plt.gcf().subplots_adjust(bottom=0.18)
plt.gcf().subplots_adjust(right=.3)
black_yellow = sns.dark_palette("yellow",10)
heatmap_list = [sns.heatmap(df, cmap=black_yellow, xticklabels=True, yticklabels=True) for df in df_list]
[heatmap_list[x].figure.savefig(file_names_list[x]+'.pdf', format='pdf') for x in range(0,len(heatmap_list))]
sns.heatmap() creates a problem while we are working in loop. To resolve this issue, the first iteration will be done individually and rest of the loop remains the same but we will add a parameter cbar=False to stop this recursion of colorbar in the loop portion.
# Set the seaborn font size.
sns.set(font_scale=0.5)
# Ensure that labels are not cut off.
plt.gcf().subplots_adjust(bottom=0.18)
plt.gcf().subplots_adjust(right=.3)
black_yellow = sns.dark_palette("yellow", 10)
hm = sns.heatmap(df_list[0], cmap=black_yellow, xticklabels=True, yticklabels=True)
hm.figure.savefig(file_names_list[0]+'.pdf', format='pdf')
heatmap_list = [sns.heatmap(df_list[i], cmap=black_yellow, xticklabels=True, yticklabels=True, cbar=False) for i in range(1, len(df_list))]
[heatmap_list[x].figure.savefig(file_names_list[x+1]+'.pdf', format='pdf') for x in range(0, len(heatmap_list))]

how to shift x axis labesl on line plot?

I'm using pandas to work with a data set and am tring to use a simple line plot with error bars to show the end results. It's all working great except that the plot looks funny.
By default, it will put my 2 data groups at the far left and right of the plot, which obscures the error bar to the point that it's not useful (the error bars in this case are key to intpretation so I want them plainly visible).
Now, I fix that problem by setting xlim to open up some space on either end of the x axis so that the error bars are plainly visible, but then I have an offset from where the x labels are to where the actual x data is.
Here is a simplified example that shows the problem:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df6 = pd.DataFrame( [-0.07,0.08] , index = ['A','B'])
df6.plot(kind='line', linewidth=2, yerr = [ [0.1,0.1],[0.1,0.1 ] ], elinewidth=2,ecolor='green')
plt.xlim(-0.2,1.2) # Make some room at ends to see error bars
plt.show()
I tried to include a plot (image) showing the problem but I cannot post images yet, having just joined up and do not have anough points yet to post images.
What I want to know is: How do I shift these labels over one tick to the right?
Thanks in advance.
Well, it turns out I found a solution, which I will jsut post here in case anyone else has this same issue in the future.
Basically, it all seems to work better in the case of a line plot if you just specify both the labels and the ticks in the same place at the same time. At least that was helpful for me. It sort of forces you to keep the length of those two lists the same, which seems to make the assignment between ticks and labels more well behaved (simple 1:1 in this case).
So I coudl fix my problem by including something like this:
plt.xticks([0, 1], ['A','B'] )
right after the xlim statement in code from original question. Now the A and B align perfectly with the place where the data is plotted, not offset from it.
Using above solution it works, but is less good-looking since now the x grid is very coarse (this is purely and aesthetic consideration). I could fix that by using a different xtick statement like:
plt.xticks([-0.2, 0, 0.2, 0.4, 0.6, 0.8, 1.0], ['','A','','','','','B',''])
This gives me nice looking grid and the data where I need it, but of course is very contrived-looking here. In the actual program I'd find a way to make that less clunky.
Hope that is of some help to fellow seekers....

Change the labels of a colorbar from increasing to decreasing values

I'd like to change the labels for the colorbar from increasing to decreasing values. When I try to do this via vmin and vmax I get the error message:
minvalue must be less than or equal to maxvalue
So, for example I'd like the colorbar to start at 20 on the left and go up to 15 on the right.
This is my code for the colorbar so far, but in this example the values go from 15 to 20 and I'd like to reverse that order:
cmap1 = mpl.cm.YlOrBr_r
norm1 = mpl.colors.Normalize(15,20)
cb1 = mpl.colorbar.ColorbarBase(colorbar1, cmap=cmap1, norm=norm1, orientation='horizontal')
cb1.set_label('magnitude')
The colorbars displayed below are probably not exactly like yours, as they are just example colorbars to function as a proof of concept.
In the following I assume you have a colorbar similar to this, with increasing values to the right:
Method 1: Inverting the x-axis
Inverts the whole x-axis of the colorbar
If you want to invert the x-axis, meaning that the values on the x-axis are descending to the right, making the colorbar "mirrored", you can make use of the ColorbarBase's ax attribute:
cb1 = mpl.colorbar.ColorbarBase(colorbar1,
cmap=cmap1,
norm=norm1,
orientation='horizontal')
cb1.ax.invert_xaxis()
This gives.the output below.
It is also possible to change the number of ticklabels by setting the colorbars locator. Here the MultipleLocator is used, although you can use many other locators as well.
from matplotlib.ticker import MultipleLocator
cb1.locator = MultipleLocator(1) # Show ticks only for each multiple of 1
cb1.update_ticks()
cb1.ax.invert_xaxis()
Method 2: Using custom ticklabels
Reverses the order of the ticklabels, keeping the orientation of the colorbar
If you want the orientation of the colorbar itself as it is, and only reverse the order in which the ticklabels appear, you can use the set_ticks and set_ticklabels methods. This is more of a "brute force" approach than the previous solution.
cb1.set_ticks(np.arange(15, 21))
cb1.set_ticklabels(np.arange(20, 14, -1))
This gives the colorbar seen below. Note that the colors are kept intact, only the tick locations and ticklabels have changed.
An alternative solution for producing the colorbar in Method 2:
cmap1 = cmap1.reversed()
cb1.ax.invert_yaxis()
works for me: variable_you_want.ax.invert_yaxis()

How to plot a rectangle behind a function over time

I'm plotting a timeseries in pandas using matplotlib and I'm trying to color a plot look like this.
I have the times for the A-F points. I've tried to get the position of them in the plot using
gcf().canvas.mpl_connect('button_press_event', debug_print_onclick_event)
and ended up with x positions being around 22'395'850 (not even close to unixtime :S)
My code basically looks like this:
plot = data.plot(legend=False) #where data is the timeseries (pandas.DataFrame).
plot.add_patch(
plt.Rectangle(
(0,22395760),
60,
45,
facecolor='green',
edgecolor='green'
)
)
plt.draw()
plt.show()
But nothings of the patch shows up.
Also tested to use time directly, it actually ran but no patch was rendered.
plt.Rectangle(
(0,datetime_D),
60,
4*pandas.datetools.Minutes(15),
facecolor='green',
edgecolor='green'
)
What is the underlying type? How should I position things in time in matplotlib? Any uglyhack working is appreciated.
You seem to have swapped x and y as first argument of Rectangle((x,y), ...).
Rectangle((22395760, 0), ...)
Instead of using a patch, plot.axvspan() seems a better match for what you want to do.
plt.gca().axvspan(date,date+2*pandas.datetools.Minute(15),facecolor='green',edge‌ color='green',alpha=0.3)

matplotlib numbers in legend

I have a couple of lines and I want to show a legend. The problem is, I can't use different styles (--, :, -.) because there are too few of them, and I can't use markers (+, *, etc.) because I need them to show some points on the lines.
So the best idea I've come up with is to use numbers. But I can't figure how I can create legends with numbers. I can even draw numbers near lines myself (to place them in the best position), but how can I then draw a legend with the numbers?
I.e. instead of:
-- H
-.- Li
I'd like something like:
1 H
2 Li
Perhaps a little Latex thrown into the mix?
#In which we make a legend; not with lines, but numbers!
import pylab as pl
pl.rc('text', usetex=True)
pl.figure(1)
pl.clf()
ax = pl.subplot(111)
pl.plot(range(0,10), 'k', label = r'\makebox[25]{1\hfill}Bla')
pl.plot(range(1,11), 'k', label = r'\makebox[25]{12\hfill}Bla12')
lgd = pl.legend(handlelength = -0.4)
for k in lgd.get_lines():
k.set_linewidth(0)
pl.draw()
pl.show()
The numbers/labels are aligned by using \makebox with specific width and \hfill to take up the space not used by your labels. Numbers are not automatic, but if you use a loop to draw your lines then you could add a counter to keep track of the numbers.
Don't know if this is part of your requirement, but the lines are removed by setting their linewidth to 0 and making the space reserved in the legend negative. Couldn't find a neater way of doing this as I believe a legend is always meant to show a line (e.g. you can't set numpoints to 0).
You could of course also just add some text in the right spot in your plot and not use a legend at all.