Plotly deactivate x axis sorting - python

I want to plot a bar chart. On the x-axis are IDs of consultants. They range between 1000 and 2000. Each consultant has a specific number of customers (y-axis).
Now I want to plot a bar chart in plotly. But plotly orders the consultant IDs ascending and interprets them as integer, but they are not. They shall be ordered like the list I give plotly.
By the way in matplotlib the order is right.
trace1 = go.Bar(
x=consultants,
y=info[0,:]
)
trace2 = go.Bar(
x=consultants,
y=info[1,:],
)
trace3 = go.Bar(
x=consultants,
y=info[2,:]
)
trace4 = go.Bar(
x=consultants,
y=info[3,:]
)
data = [trace1, trace2, trace3, trace4]
layout = go.Layout(
barmode='stack',
xaxis=dict(
categoryorder='array',
categoryarray=consultants,
titlefont=dict(
size=18,
color='black'),
showticklabels=True,
tickfont=dict(
size=16,
color='black',
),
tickangle=20
),
yaxis=dict(
title='Number of customers',
titlefont=dict(
size=18,
color='black'),
showgrid=True,
showline=False,
showticklabels=True,
tickfont=dict(
size=16,
color='black')
),
)
fig = go.Figure(data=data, layout=layout)
py.iplot(fig, filename='stacked-bar')

The lastest version of Plotly now has a variable in the layout options to specify a categorical layout for the X axis:
fig.update_layout(
xaxis_type = 'category'
)

Interestingly Plotly seems to ignore categoryorder for integers but disabling of sorting can be achieved by passing type='category in xaxis in layout.
type ( enumerated : "-" | "linear" | "log" | "date" | "category" )
default: "-"
Sets the axis type. By default, plotly attempts to
determined the axis type by looking into the data of the traces that
referenced the axis in question.
import plotly
import plotly.graph_objs as go
import numpy as np
plotly.offline.init_notebook_mode()
consultants = [1, 3, 2, 5, 4]
info = np.random.randint(100, size=(5,5))
data = []
for i in range(len(info)):
data.append(go.Bar(x=consultants,
y=info[i,:]))
layout = go.Layout(barmode='stack',
xaxis=dict(type='category'),
yaxis=dict(title='Number of customers'))
fig = go.Figure(data=data, layout=layout)
plotly.offline.iplot(fig, filename='stacked-bar')

Related

Plotly go.Bar : Add custom legend labels based on values

I have a dataframe with positive and negative values in one column. I am using plotly barplot, and I'd like customize legend labels based on the value.
Here's a mock pandas DataFrame:
df = pd.DataFrame({'Date': [07-2020, 08-2020, 09-2020, 10-2020],
'Value': [3, -2, 4, -1] })
df["Color"] = np.where(df["Value"]<0, 'rgb(0,0,255)', 'rgb(255,0,0)')
df["Name"] = np.where(df["Value"]<0, 'Low', 'High')
fig = go.Figure(
data=[
go.Bar(
x=df["Date"],
y=df["Value"],
color=df['Name'],
marker_color=df['Color']
),
],
layout=go.Layout(
xaxis=dict(
tickangle=60,
tickfont=dict(family="Rockwell", color="crimson", size=14)
),
yaxis=dict(
title="Net Change",
showticklabels=True
),
barmode="stack",
)
)
How do I add legend labels Low when value is negative and High when positive?
I wasn't sure if your legend label was a legend or an annotation label, so I added support for both. To annotate a bar chart, you can specify it in the text The display position will automatically determine the location. To add high and low to the legend, I created a high data frame and a low data frame and gave each a name. As a layout, we specify the tick positions and display names in order to arrange them in data frame order.
import pandas as pd
import plotly.graph_objects as go
import numpy as np
df = pd.DataFrame({'Date': ['07-2020', '08-2020', '09-2020', '10-2020'], 'Value': [3, -2, 4, -1] })
df["Color"] = np.where(df["Value"]<0, 'rgb(0,0,255)', 'rgb(255,0,0)')
df["Name"] = np.where(df["Value"]<0, 'Low', 'High')
df_high = df[df['Name'] == 'High']
df_Low = df[df['Name'] == 'Low']
fig = go.Figure(data=[
go.Bar(
x=[0,2],
y=df_high["Value"],
text=df_high["Name"],
textposition='auto',
name='High',
marker_color=df_high['Color']
),],)
fig.add_trace(
go.Bar(
x=[1,3],
y=df_Low["Value"],
text=df_Low["Name"],
textposition='auto',
name='Low',
marker_color=df_Low['Color'])
)
fig.update_layout(
xaxis=dict(
tickangle=60,
tickfont=dict(family="Rockwell", color="crimson", size=14),
tickvals=[0,1,2,3],
ticktext=df['Date']
),
yaxis=dict(
title="Net Change",
showticklabels=True
),
barmode="stack",
)
fig.show()

Adding a secondary axis in Plotly Python

I'm working with a Dash graph object and I'm fairly new to it. I'm attempting to pass in a graph that has 2 scatter charts and a bar chart on the same figure but I'd like the bar chart (green) to be on it's own secondary y axis so it looks better than it does here:
Now from what I understand about Dash, I have to pass a go.Figure() object so I have a function which defines the data and the layout. I saw in the plotly documentation that you can use plotly express add secondary axis but I'm not sure how to do that within my frame work here. Any help would be greatly appreciated!
Here's my code:
def update_running_graph(n_intervals):
df = pd.read_csv(filename)
trace1 = go.Scatter(x=df['Timestamp'],
y=df['CLE'],
name='Crude',
mode='lines+markers')
trace2 = go.Scatter(x=df['Timestamp'],
y=df['y_pred'],
name='Model',
mode='lines+markers')
trace3 = go.Bar(x=df['Timestamp'],
y=df['ModelDiff'],
name='Diff',
)
data = [trace1, trace2,trace3]
layout = go.Layout(title='CLE vs Model')
return go.Figure(data=data, layout=layout)
To add a secondary y-axis in dash you could do the following:
def update_running_graph(n_intervals):
df = pd.read_csv(filename)
trace1 = go.Scatter(x=df['Timestamp'],
y=df['CLE'],
name='Crude',
mode='lines+markers',
yaxis='y1')
trace2 = go.Scatter(x=df['Timestamp'],
y=df['y_pred'],
name='Model',
mode='lines+markers',
yaxis='y1')
trace3 = go.Bar(x=df['Timestamp'],
y=df['ModelDiff'],
name='Diff',
yaxis='y2'
)
data = [trace1, trace2,trace3]
layout = go.Layout(title='CLE vs Model',
yaxis=dict(title='Crude and Model'),
yaxis2=dict(title='Moddel Difference',
overlaying='y',
side='right'))
return go.Figure(data=data, layout=layout)
you can add more y-axis they always need to have the form of yi with i the i-th axis. Then in the layout you can specify the layout of the i-th axis with yaxisi=dict(...).
This documentation page should be of use. Just modify to fit your code, since trace1 and trace2 appear to be on the same scale, just set trace3 to the secondary axis scale and you should be set. Below is an example with just only 2 but adding a third should not be too difficult.
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# Create figure with secondary y-axis
fig = make_subplots(specs=[[{"secondary_y": True}]])
# Add traces
fig.add_trace(
go.Scatter(x=[1, 2, 3], y=[40, 50, 60], name="yaxis data"),
secondary_y=False,
)
fig.add_trace(
go.Scatter(x=[2, 3, 4], y=[4, 5, 6], name="yaxis2 data"),
secondary_y=True,
)
# Add figure title
fig.update_layout(
title_text="Double Y Axis Example"
)
# Set x-axis title
fig.update_xaxes(title_text="xaxis title")
# Set y-axes titles
fig.update_yaxes(title_text="<b>primary</b> yaxis title", secondary_y=False)
fig.update_yaxes(title_text="<b>secondary</b> yaxis title", secondary_y=True)
fig.show()
Cheers!

how to set the vertical scale of pyplot linear figure

I have a code that displays geologic well log in python using plotly,
the scale is linear and I set the range of it based on the dataframe index
I need to keep the scale as linear but want to set the vertical scale or the y-axis scale for example to be 1:100 how to achieve that
layout = go.Layout(
title='VSH',
autosize=False,
width=500,
height=1500,
yaxis=dict(
title='DEPT',
showgrid=True,
showticklabels=True,
gridcolor='#bdbdbd',
gridwidth=2
),
xaxis=dict(
title='Vsh',
showgrid=True,
showticklabels=True,
gridcolor='#bdbdbd',
gridwidth=2
)
)
df = df.loc[(df.index >= int(top)) & (df.index <= int(base))]
trace1 = go.Scatter(x = df['Vsh']/10 , y = df.index , mode='lines')
fig = go.Figure(data=[trace1] , layout = layout)
iplot(fig)
Just create a list (for example, from 1 to 100):
list1 = [i for i in range(0, 101)]
and added two parameters to yaxis in layout:
yaxis=dict(tickvals=[i for i in range(len(list1))],
ticktext=list1)
You can read more about ticktext and tickvals in plotly docs: 1 and 2.

Plotly offline time series with multiple axis

I have a plotly offline chart with datetime and single y axis,now I want to add one more line in y axis.
original code:
from plotly.offline import download_plotlyjs,init_notebook_mode,plot
plot([Scatter(x=datetimefield,y=value1)],filename="plotly.html")
To add multiple I am tried to tweak the y parameter :
plot([Scatter(x=datecolumn,y=[value1,value2])],filename="plotly.html")
But this doesn't seems to be working.
x=datetime field is time series based
y=value1 & value 2 are two pandas columns
Note:- Two axis are in different datatype one is numeric other is percentage
How to tweak the y parameter in offline mode of plotly to have multiple axis.
Found solution:
from plotly.offline import download_plotlyjs,init_notebook_mode,plot
import plotly.graph_objs as go
trace1 = go.Scatter(
x=df.datetimecolumn,
y=df.value1)
trace2 = go.Scatter(
x=df.datetimecolumn,
y=df.value2)
data = [trace1, trace2]
layout = go.Layout(
xaxis=dict(
zeroline=True,
showline=True,
mirror='ticks',
gridcolor='#bdbdbd',
gridwidth=2,
zerolinecolor='#969696',
zerolinewidth=4,
linecolor='#636363',
linewidth=6
),
yaxis=dict(
zeroline=True,
showline=True,
mirror='ticks',
gridcolor='#bdbdbd',
gridwidth=2,
zerolinecolor='#969696',
zerolinewidth=4,
linecolor='#636363',
linewidth=6
)
)
fig = go.Figure(data=data, layout=layout)
plot(fig)

Offline plot ignoring layout parameters in plotly python API

I'm producing a 3D surface plot with medium success, but some parameters just don't respond to my flags, such as axis ranges, labels and log scale, but some things do, such as overall title and aspect ratio. I can't understand the problem, can anyone see something I'm doing wrong?
Thanks
def make3dPlot(surfaceMatrix, regionStart, regionEnd):
data = [go.Surface(z=surfaceMatrix)]
#data = [go.Surface(z=[[1, 2, 3, 4, 9],[4, 1, 3, 7, 9],[5, 4, 7, 2, 9]])]
layout = go.Layout(
title=args.i,
autosize=True,
width=1600,
height=1000,
yaxis=dict(
title='Particle Size',
titlefont=dict(
family='Arial, sans-serif',
size=18,
color='lightgrey'
),
type='log',
autorange=True,
#range=[regionStart, RegionEnd]
),
xaxis=dict(
title="Genomic Co-ordinates",
titlefont=dict(
family='Arial, sans-serif',
size=18,
color='lightgrey'
),
#type='log',
#autorange=False,
range=[10, 15]#regionStart, regionEnd]
),
scene=dict(
aspectratio=dict(x=3, y=1, z=1),
aspectmode = 'manual'
)
)
fig = go.Figure(data=data, layout=layout)
plotly.offline.plot(fig)
With the Mock data it looks like this, with unchanged axis and no labels:
As per docs, xaxis, yaxis and zaxis for 3D plots in plotly are part of Scene, not Layout.
Example:
from plotly.offline import iplot, init_notebook_mode
import numpy as np
from plotly.graph_objs import Surface, Layout, Scene
init_notebook_mode()
x, y = np.mgrid[-2*np.pi:2*np.pi:300j, -2:2:300j]
surface = Surface(
x=x, y=y, z=-np.cos(x)+y**2/2
)
iplot([surface])
layout = Layout(scene=Scene(xaxis=dict(range=[-1,1])))
iplot(dict(data=[surface], layout=layout))
See also this question.

Categories

Resources