plotly rendering bug with python 3d plot - python

I am using plotly and python to visualize 3D data and I encoutered a strange phenomenon when plotting some data. The following code visualizes data of the form (3,20) each for the direction x,y and z.
import numpy as np
import plotly.io as pio
import plotly.graph_objects as go
data = np.array([
[4.41568822e+05, 4.41568474e+05, 4.41567958e+05, 4.41567603e+05,
4.41567249e+05, 4.41566952e+05, 4.41566619e+05, 4.41566324e+05,
4.41566021e+05, 4.41565737e+05, 4.41565435e+05, 4.41565098e+05,
4.41564807e+05, 4.41564472e+05, 4.41564121e+05, 4.41563860e+05,
4.41563538e+05, 4.41563226e+05, 4.41562933e+05, 4.41562641e+05],
[5.71148897e+06, 5.71148909e+06, 5.71148928e+06, 5.71148942e+06,
5.71148955e+06, 5.71148967e+06, 5.71148981e+06, 5.71148993e+06,
5.71149006e+06, 5.71149019e+06, 5.71149032e+06, 5.71149047e+06,
5.71149060e+06, 5.71149076e+06, 5.71149093e+06, 5.71149106e+06,
5.71149122e+06, 5.71149137e+06, 5.71149153e+06, 5.71149168e+06],
[1.86559470e+02, 1.86547226e+02, 1.86529120e+02, 1.86516642e+02,
1.86504156e+02, 1.86493615e+02, 1.86481706e+02, 1.86471064e+02,
1.86460026e+02, 1.86449593e+02, 1.86438417e+02, 1.86425803e+02,
1.86414828e+02, 1.86402073e+02, 1.86388572e+02, 1.86378511e+02,
1.86366018e+02, 1.86353893e+02, 1.86342497e+02, 1.86331154e+02]])
fig = go.Figure(data=[go.Scatter3d(x=data[0,:], y=data[1,:], z=data[2,:],
mode='markers',
marker=dict(size=3),
)])
pio.show(fig, renderer='browser')
I have compared the result (top) below with a matplotlib plot of the same data (bottom).
The points that represent a relatively straight line are represented in Plotly in steps rather than in a line, and I don't really understand why.
Can someone explain to me why the points are displayed like this in plotly and how I can fix this problem?
I appreciate any help I can get!

It looks like an issue with how Plotly is interpreting your numpy array. Your arrays look to be nested which would explain why instead of plotly drawing the plot as a continuous line they are being rendered as steps.

Related

How do you put the x axis labels on the top of the heatmap created with seaborn? [duplicate]

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()

Visualize scatter plot with labels on each point

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

Unable to draw KDE on python

I've created a Brownian motion and then I have taken the last values of 1000 entries repeated 10000 times. I was able to plot the histogram using the following code as follows:
import seaborn as sns
import matplotlib.pyplot as plt
\\BM represents list of values generated by the Brownian motion
fig, (ax1,ax2) = plt.subplots(2)
ax1.hist(BM[:,-1],12)
I've been able to draw the KDE as follows, however i unable to merge the two diagrams together. Can someone please help me?
sns.kdeplot(data=BM[:,-1])
Try with sns.kdeplot(BM['col1']) where 'col1' is the name of the column you want to plot.
I'll give you a reproducible example that works for me.
import seaborn as sns
import pandas as pd
import numpy as np
BM = pd.DataFrame(np.array([-0.00871515, -0.0001227 , -0.01449098, 0.01808527, 0.00074193, 0.01145541]
, columns=['col1'])
BM.head(2)
col1
0 -0.008715
1 -0.000123
sns.kdeplot(BM['col1'])
Edit based on your additional question:
To have the histogram and a kde plot use this one:
sns.distplot(BM['col1'])

How to plot time series graph in jupyter?

I have tried to plot the data in order to achieve something like this:
But I could not and I just achieved this graph with plotly:
Here is the small sample of my data
Does anyone know how to achieve that graph?
Thanks in advance
You'll find a lot of good stuff on timeseries on plotly.ly/python. Still, I'd like to share some practical details that I find very useful:
organize your data in a pandas dataframe
set up a basic plotly structure using fig=go.Figure(go.Scatter())
Make your desired additions to that structure using fig.add_traces(go.Scatter())
Plot:
Code:
import plotly.graph_objects as go
import pandas as pd
import numpy as np
# random data or other data sources
np.random.seed(123)
observations = 200
timestep = np.arange(0, observations/10, 0.1)
dates = pd.date_range('1/1/2020', periods=observations)
val1 = np.sin(timestep)
val2=val1+np.random.uniform(low=-1, high=1, size=observations)#.tolist()
# organize data in a pandas dataframe
df= pd.DataFrame({'Timestep':timestep, 'Date':dates,
'Value_1':val1,
'Value_2':val2})
# Main plotly figure structure
fig = go.Figure([go.Scatter(x=df['Date'], y=df['Value_2'],
marker_color='black',
opacity=0.6,
name='Value 1')])
# One of many possible additions
fig.add_traces([go.Scatter(x=df['Date'], y=df['Value_1'],
marker_color='blue',
name='Value 2')])
# plot figure
fig.show()

pandas matplotlib margin with x axis

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()

Categories

Resources