Is there any way to change cell size of Seaborn heatmap?
I found this but I cannot get it work as expected.
So, I have long text in y-axis labels. Since all of the texts are chopped off, I would like to shrink cell size of the heatmap much smaller. I don't need that big rectangle. (Highlighted just for example.)
(I hid label names.)
When I change the figure size by something like,
plt.figure(figsize=(8, 6)) or
figure.set_size_inches(12, 12)
the cell gets bigger as well so the texts remain chopped off.
Here is the code.
sns.set(font_scale=1.2)
ax0 = plt.axes()
ax1 = sns.heatmap(hmap, cbar=0, cmap="YlGnBu",linewidths=2, ax=ax0,vmax=3000, vmin=0)
ax1.set_title('test heatmap')
for item in ax1.get_yticklabels():
item.set_rotation(0)
for item in ax1.get_xticklabels():
item.set_rotation(0)
figure = plt.gcf() # get current figure
figure.set_size_inches(12, 12)
plt.savefig('test.png') , dpi=400)
Try using the square=True argument in your sns.heatmap call. This will constrain the heat map cells to a square aspect ratio.
ax1 = sns.heatmap(hmap, cbar=0, cmap="YlGnBu",linewidths=2, ax=ax0,vmax=3000, vmin=0, square=True)
You don't actually want to change the cell size but you want to shrink the size of the axes. Ways to to this:
use plt.tight_layout()
Provide more space to the side e.g. via fig.subplots_adjust(left=0.4)
Create an axes, which has the size you want, ax1 = fig.add_axes([0.4,0.2,0.5,0.6]) (where the numbers are [left, bottom, width, height] and use this axes to plot the heatmap, sns.heatmap(... , ax=ax1).
Related
I'm bringing this question from Altair's github. (https://github.com/altair-viz/altair/issues/2456) Is there a way to get the Scale on Y-axis in the bottom chart to respond to the selection brush? I'd like to be able to pan around the top chart with a selection and see the zoomed-in results in the bottom chart. If I uncomment the alt.Y, then both the X and Y axes show Years and it's messed up. Is there a way to pass just an X or Y value in the 'brush' maybe? Thank you very much!
brush = alt.selection_interval(init={'x':[1950, 1970], 'y':[1500000, 2500000]}, encodings=['x', 'y'])
base = alt.Chart().mark_line().encode(
x=alt.X('Year:Q', title=None),
y='Deaths:Q',
color='Entity:N'
)
alt.vconcat(
base.add_selection(brush).encode().properties(height=150, width=150),
base.encode(
alt.X('Year:Q', scale=alt.Scale(domain=brush)),
#alt.Y('Deaths:Q', scale=alt.Scale(domain=brush)) # (un)commenting this line makes it work/fail only along the x-axis
).properties(
height=500, width=500
),
data='https://vega.github.io/vega-datasets/data/disasters.csv'
)
Yes, see Open the Chart in the Vega Editor
It filters the data of the 2nd chart using a filter transform on the brush param.
I'm trying to display the exact values on one axis of the color bar and a basic scale on the other. However, some of the exact values are so close together their names overlap on the color bar. Is there a way for me to make the overlapping names appear as a list or just to the side the other values name? I've already tried rotation of the labels, setting vmin/vmax in the color bar method, and setting the ylim's of the second axis. I'm at a lose at what to try next. It feels like this is something matplotlib would allow but I can't find what method or kwargs that allow this manipulation. Many of the commented out tlines are the attempts I've made with help from many posts on StackOverflow. Thank you!!
Previous code deleted for clarity
UPDATE: Paul H here is a workable example with the same issue I'm trying to fix
# Make random data with same issue
x, y = np.linspace(-3, 1.5, 20), np.linspace(0, 0.5, 20)
# two different ranges used to simulate the same issue in my data
fake_phase = np.append(np.random.random_sample(15), np.arange(0.0, .005, 0.001))
fake_labels = np.array(['V439Oph', 'ALVir', 'YZVir', 'XXVir', 'V716Oph', 'BFSer', 'BLHer',
'RXLib', 'CEHer', 'V465Oph', 'V1180Sgr', 'CSCas', 'DQAnd', 'IXCas',
'UYEri', 'TWCap', 'AUPeg', 'MZCyg', 'SWTau', 'TXDel'], dtype=object)
# Plot data
fig, ax = plt.subplots(1,1,figsize=(15,10))
plt.tight_layout()
plt.plot(x, y, marker='.', ms=17, mew=2, linestyle='none')
# Make the same colorbar
norm = cm.colors.Normalize(vmin=0.0, vmax=1.0, clip=False)
cbar = fig.colorbar(cm.ScalarMappable(norm=norm, cmap='rainbow'), ax=ax, extend='both',
orientation='vertical', pad=0.005, use_gridspec=True)
cbar.set_ticks(fake_phase)
cbar.set_ticklabels(fake_labels)
cbar.ax.tick_params(which='major', labelsize='large', width=1.5, length=6)
cbar.set_label(label='Phase', size='xx-large', labelpad=40)
cbar.ax.set_aspect('auto')
ax2 = cbar.ax.twinx()
pos = cbar.ax.get_position()
pos.x0 += 0.1
ax2.set_position(pos)
plt.show();
The output of this code: Output of workable example
My issue is that the secondary axis on the colorbar (left axis) has values that are so close together their labels overlap. I'm hoping to find a way to space the labels so they are readable. I thought I found a way to accomplish this using axis.set_ticklabels() (set_ticklabels() documentation. In the **kargs section of the doc it references using text properties. In the text properties documentation text properties doc the property 'y' says you can set the y-position of the text. However, when I add this keyword to set_ticklabels() I get an error that the keyword is not recognized.. I've tried adding the property 'y' as a keyword and attribute but I get a keyword error or does not have that attribute error...
I'm calling the property wrong but I've never gotten this detailed in editing these parameters. I honestly don't know if this is the best way to solve this, but it's the closest I've gotten so far. I was hoping to use it to offset the labels so they were stacked vertically on top of each other in the same order but far enough apart that the label is readable.
Thanks for any input!
I am using a seaborn scatterplot and just started using different point sizes.
sns.scatterplot(x='X [um]', y='Y [um]', hue='label', size='size', data=data)
All works perfectly but I'd like to remove the 'size' from the legend seen in picture:
The upper part with CH1, etc. shall remain the same but I'd want the lower part where the sizes are listed to vanish.
I use the get_legend_handles_labels() functionality to index the labels. Using indexing, I ensure that the final printed image only contains the first 13 labels in your legend.
g = sns.scatterplot(x='X [um]', y='Y [um]', hue='label', size='size', data=data)
h,l = g.get_legend_handles_labels()
plt.legend(h[0:13],l[0:13],bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
plt.show(g)
I'm trying to get the plot points in a scatter graph to size according to the frequency of values in a column of data. The data is coming from a questionnaire.
My questions are: What am I doing wrong, and what can I do to fix it?
I can push out a simple plot with x and y values coming from 2 columns of data. The X axis represents a level (1-100), and the Y axis represents a choice users can make for each level (1-4). For this plot I want to track how many people choose 1-4 on each level - so I need to capture that 1-4 has been selected, then indicate how many times.
Simple plot works fine, though those points have multiple occurrences.
Here's the code for that:
# Set up the graph
WT_Number = data.wt # This is the X axis
CFG_Number = data.cfg # This is the Y axis
wt_cfg_plot = figure(plot_width=1000, plot_height=400,
title="Control Form Groups chosen by WT unit")
# Set up the plot points, including the Hover Tool
cr = wt_cfg_plot.scatter(WT_Number, CFG_Number, size=7,
fill_color="blue",
line_color=None, alpha=0.7, hover_fill_color="firebrick",
hover_line_color=None, hover_alpha=1)
Problem: I then added a value count and set it as the size, to get the plot points to adjust according to the value frequency. But now it pumps out this chart and throws an error:
Plot points are reacting to the code, but now they're doing their own thing.
I added a variable for the value counts (cfg_freq), and used that as the size:
cfg_freq = data['cfg'].value_counts()*4
cr = wt_cfg_plot.scatter(WT_Number, CFG_Number, size=cfg_freq, fill_color="blue",
line_color=None, alpha=0.7, hover_fill_color="firebrick",
hover_line_color=None, hover_alpha=1)
Here's the the last part of the error being thrown:
File "/Applications/anaconda/lib/python3.5/site-packages/bokeh/core/properties.py", line 722, in setattr
(name, self.class.name, text, nice_join(matches)))
AttributeError: unexpected attribute 'size' to Chart, possible attributes are above, background_fill_alpha, background_fill_color, below, border_fill_alpha, border_fill_color, disabled, extra_x_ranges, extra_y_ranges, h_symmetry, height, hidpi, left, legend, lod_factor, lod_interval, lod_threshold, lod_timeout, logo, min_border, min_border_bottom, min_border_left, min_border_right, min_border_top, name, outline_line_alpha, outline_line_cap, outline_line_color, outline_line_dash, outline_line_dash_offset, outline_line_join, outline_line_width, plot_height, plot_width, renderers, responsive, right, tags, title, title_standoff, title_text_align, title_text_alpha, title_text_baseline, title_text_color, title_text_font, title_text_font_size, title_text_font_style, tool_events, toolbar_location, tools, v_symmetry, webgl, width, x_mapper_type, x_range, xgrid, xlabel, xscale, y_mapper_type, y_range, ygrid, ylabel or yscale
I want to increase the size of the numbers which label my legend using D3. The legend is made as follows:
map.legend_axes = d3.svg.axis()
.scale(map.legend_scales)
.orient('bottom')
.tickSize(map.settings.legend.ticks);
Is there an argument I can pass which will increase the size of the numbers?
Add a CSS class that increases the font size and then add that class to the text on the axis:
d3.selectAll("axisElement")
.classed("large-font", true);