This question already has answers here:
How to move labels from bottom to top without adding "ticks"
(2 answers)
How to have the axis ticks in both top and bottom, left and right of a heatmap
(2 answers)
Closed 4 months ago.
I have created a heatmap using the seaborn and matplotlib package in python, and while it is perfectly suited for my current needs, I really would prefer to have the labels on the x-axis of the heatmap to be placed at the top of the plot, rather than at the bottom (which seems to be its default).
So an abridged form of my data looks like this:
NP NP1 NP2 NP3 NP4 NP5
identifier
A1BG~P04217 -0.094045 0.012229 0.102279 1.319618 0.002383
A2M~P01023 -0.805089 -0.477339 -0.351341 0.089735 -0.473815
AARS1~P49588 0.081827 -0.099849 -0.287426 0.101588 0.136366
ABCB6~Q9NP58 0.109911 0.458039 -0.039325 -0.484872 1.905586
ABCC1~I3L4X2 -0.560155 0.580285 0.012868 0.291303 -0.407900
ABCC4~O15439 0.055264 0.138630 -0.204665 0.191241 0.304999
ABCE1~P61221 -0.510108 -0.059724 -0.233365 0.078956 -0.651327
ABCF1~Q8NE71 -0.348526 -0.135414 -0.390021 -0.190644 -0.276303
ABHD10~Q9NUJ1 0.237959 -2.060834 0.325901 -0.778036 -4.046345
ABHD11~Q8NFV4 0.294587 1.193258 -0.797294 -0.148064 -1.153391
And when I use the following code:
import seaborn as sns
import matplotlib as plt
fig, ax = plt.subplots(figsize=(10,30))
ax = sns.heatmap(df_example, annot=True, xticklabels=True)
I get this kind of plot:
https://imgpile.com/i/T3zPH1
I should note that the this plot was made from the abridged dataframe above, the actual dataframe has thousands of identifiers, making it very long.
But as you can see, the labels on the x axis only appear at the bottom. I have been trying to get them to appear on the top, but seaborn doesn't seem to allow this kind of formatting.
So I have also tried using plotly express, but while I solve the issue of placing my x-axis labels on top, I have been completely unable to format the heat map as I had before using seaborn. The following code:
import plotly.express as px
fig = px.imshow(df_example, width= 500, height=6000)
fig.update_xaxes(side="top")
fig.show()
yields this kind of plot: https://imgpile.com/i/T3zF42.
I have tried many times to reformat it using the documentation from plotly (https://plotly.com/python/heatmaps/), but I can't seem to get it to work. When one thing is fixed, another problem arises. I really just want to keep using the seaborn based code as above, and just fix the x-axis labels. I'm also happy to have the x-axis label at both the top and bottom of the plot, but I can't get that work presently. Can someone advise me on what to do here?
Ok, so I did a bit more research, and it turns out you can add the follow code with the seaborn approach:
plt.tick_params(axis='both', which='major', labelsize=10, labelbottom = False, bottom=False, top = False, labeltop=True)
If your data are stored into csv file, you can use this code:
import pandas as pd
import plotly.express as px
df = pd.read_csv("file.csv").round(2)
fig = px.imshow(df.iloc[:,1:],
y = df['identifier'],
text_auto=True, aspect="auto")
fig.show()
The data in the CSV file are in the following format:
identifier NP1 NP2 NP3 NP4 NP5
A1BG~P04217 -0.094045 0.012229 0.102279 1.319618 0.002383
A2M~P01023 -0.805089 -0.477339 -0.351341 0.089735 -0.473815
AARS1~P49588 0.081827 -0.099849 -0.287426 0.101588 0.136366
ABCB6~Q9NP58 0.109911 0.458039 -0.039325 -0.484872 1.905586
ABCC1~I3L4X2 -0.560155 0.580285 0.012868 0.291303 -0.407900
ABCC4~O15439 0.055264 0.138630 -0.204665 0.191241 0.304999
ABCE1~P61221 -0.510108 -0.059724 -0.233365 0.078956 -0.651327
ABCF1~Q8NE71 -0.348526 -0.135414 -0.390021 -0.190644 -0.276303
ABHD10~Q9NUJ1 0.237959 -2.060834 0.325901 -0.778036 -4.046345
ABHD11~Q8NFV4 0.294587 1.193258 -0.797294 -0.148064 -1.153391
Now let's display the xaxis top of the heatmap by adding:
fig.update_layout(xaxis = dict(side ="top"))
Alternative solution if you have old version of Plotly:
fig = go.Figure(data=go.Heatmap(
x=df.columns[1:],
y=df.identifier,
z=df.iloc[:,1:],
text=df.iloc[:,1:],
texttemplate="%{text}"))
fig.update_layout(xaxis = dict(side ="top"))
fig.show()
i have a dataset longitude, latitude, its city, and the status of its city of coronavirus.
I want to give a label on each point for city name. i dont have any idea if i use plt.text() one by one to give the labels.
Here the code i use for creating dataset
jabar = [
['Depok',-6.385589,106.830711,'sedang',600],
['Tasikmalaya',-7.319563,108.202972,'sedang',600],
['Ciamis',-7.3299,108.3323,'sedang',600],
['Kuningan',-7.0138,108.5701,'sedang',600],
['Bogor',-6.497641,106.828224,'sedang',600],
['Bogor',-6.595038,106.816635,'sedang',600],
['Cirebon',-6.737246,108.550659,'sedang',600],
['Majalengka',-6.8364,108.2274,'sedang',600],
['Sumedang',-6.8381,107.9275,'sedang',600],
['Indramayu',-6.327583,108.324936,'sedang',600],
['Subang',-6.571589,107.758736,'sedang',600],
['Purwakarta',-6.538681,107.449944,'sedang',600],
['Karawang',-6.3227,107.3376,'sedang',600],
['Bekasi',-6.241586,106.992416,'sedang',600],
['Pangandaran',-7.6833,108.6500,'sedang',600],
['Sukabumi',-6.923700,106.928726,'sedang',600],
['Cimahi',-6.8841,107.5413,'sedang',600],
['Banjar',-7.374585,108.558189,'sedang',600],
['Cianjur',-6.734679,107.041252,'sedang',600],
['Bandung',-6.914864,107.608238,'tinggi',1000],
['Bandung',-6.905977,107.613144,'tinggi',1000],
['Bandung',-6.914744,107.609810,'tinggi',1000],
['Garut',-7.227906,107.908699,'sedang',600],
['Bandung Barat',-7.025253,107.519760,'sedang',600]]
features=['City','longitude','latitude','status','status_size']
risk_map = pd.DataFrame(jabar, columns=features)
and here it is the code i create for visualize to give the label each points.
import matplotlib.pyplot as plt
plt.figure(figsize=(14,8))
plt.scatter(risk_map['latitude'],risk_map['longitude'], c='orange',
s=risk_map['status_size'], label='Risk region')
plt.title('Peta Sebaran Covid-19', fontsize=20)
plt.text(-7.227906,107.908699,'Garut')
plt.show()
actually i have two datasets exclude the code i write above, the another is about confirmed-positive-cases-covid-region which is the point about more than 500.000 points.
I merge this two dataset to get the risk-region. But i get trouble when i want to giva a labels on each point.
the plt.text() i write above is example to give a label on a point. it is impossible if i write one by one as same as the text code because my computer got cracked and blank after i executed that code.
Anyone have any idea to give a label on each points that i write the code above?
thank in advance
plotly mapbox provides very simple to use capabilities for what you want
your longitude, latitude values are reversed. See in code sample below I've reversed them
import plotly.express as px
import pandas as pd
jabar = [
['Depok',-6.385589,106.830711,'sedang',600],
['Tasikmalaya',-7.319563,108.202972,'sedang',600],
['Ciamis',-7.3299,108.3323,'sedang',600],
['Kuningan',-7.0138,108.5701,'sedang',600],
['Bogor',-6.497641,106.828224,'sedang',600],
['Bogor',-6.595038,106.816635,'sedang',600],
['Cirebon',-6.737246,108.550659,'sedang',600],
['Majalengka',-6.8364,108.2274,'sedang',600],
['Sumedang',-6.8381,107.9275,'sedang',600],
['Indramayu',-6.327583,108.324936,'sedang',600],
['Subang',-6.571589,107.758736,'sedang',600],
['Purwakarta',-6.538681,107.449944,'sedang',600],
['Karawang',-6.3227,107.3376,'sedang',600],
['Bekasi',-6.241586,106.992416,'sedang',600],
['Pangandaran',-7.6833,108.6500,'sedang',600],
['Sukabumi',-6.923700,106.928726,'sedang',600],
['Cimahi',-6.8841,107.5413,'sedang',600],
['Banjar',-7.374585,108.558189,'sedang',600],
['Cianjur',-6.734679,107.041252,'sedang',600],
['Bandung',-6.914864,107.608238,'tinggi',1000],
['Bandung',-6.905977,107.613144,'tinggi',1000],
['Bandung',-6.914744,107.609810,'tinggi',1000],
['Garut',-7.227906,107.908699,'sedang',600],
['Bandung Barat',-7.025253,107.519760,'sedang',600]]
features=['City','longitude','latitude','status','status_size']
risk_map = pd.DataFrame(jabar, columns=features)
fig = px.scatter_mapbox(risk_map, lon="latitude", lat="longitude",
color="status", hover_name="City",size="status_size"
)
fig.update_layout(mapbox={"style":"carto-positron"})
fig
I am trying to create line chart using pandas data frame and matplotlib. I am using following code to create line chart.
import pandas as pd
import matplotlib.pyplot as plt
data = {
'Quarter': ['Q1-2018', 'Q2-2018', 'Q3-2018', 'Q4-2018', 'Q1-2019'],
'Data': [256339, 265555, 274880, 211128, 0]
}
dataset2 = pd.DataFrame(data=data)
ax3 = dataset2[['Quarter', 'Data']].plot.line(x='Quarter', y='Data',
legend=False)
ax3.margins(x=0.1)
plt.show()
Which produces following result
As you can see, start and end of line is starting and ending at edge of the plot.
What I am trying to achieve is to have some space at the start and end of line chart like below.
I tried setting x margin by using ax3.margins(x=0.1) but it does not do any thing.
How do I add some space to start and end of chart so that line does not stick to edges?
In pandas 0.23 you would get the correct plot with margins as desired, yet without labels. This "bug" seems to have been fixed in pandas 0.24, at the expense of another undesired behaviour.
That is, pandas fixes the limits of categorical plots and sets the ticklabels to the positions that would look correct if limits are not changed. While you could in theory unfix the limits (ax.set_xlim(None, None)) and let the axes autoscale (ax.autoscale()), the result will be a incorrectly labelled plot.
I doubt there is any reasoning behind this, it's rather an oversight in the pandas source. This pandas issue best describes the problem, which then boils down to this 5 year old issue.
In any case, for categorical plots, consider using matplotlib directly. It's categorical feature is pretty stable by now and easy to use:
import pandas as pd
import matplotlib.pyplot as plt
data = {
'Quarter': ['Q1-2018', 'Q2-2018', 'Q3-2018', 'Q4-2018', 'Q1-2019'],
'Data': [1,3,2,4,1]
}
df = pd.DataFrame(data=data)
plt.plot("Quarter", "Data", data=df)
plt.show()