plotly.py icon indicating copy to clipboard operation
plotly.py copied to clipboard

fillpattern is not working for plotly.Scatter

Open shubhamgupta568 opened this issue 3 years ago • 3 comments

import pandas as pd
input_data = {'Series Label': ['A Company','B Company'], 
					'RMS': [3,5],'AROS': [17,55],'Sales': [50000,20000]}
df = pd.DataFrame.from_dict(input_data)
bandInfo = {"Slope":0.48200011277657,"Intercept":0.440821363259248,"BandWidth":0.124669723885567, "RSquared":0.8}

def _CalcOriginalPoint (x:float, bandWidth:float, minX: float, maxX: float, minY:float, maxY:float, bandInfo):
    if bandInfo["Slope"] == 0:
        x = min (max (x, minX), maxX)
        return {"X": x, "Y": (bandInfo["Intercept"] + bandWidth) * 100}
    elif (math.isnan (bandInfo["Slope"])):
        x = min (max (x, minX), maxX)
        if (x == minX):
            y = minY + bandWidth
        else :
            y = maxY + bandWidth
        return {"X": x, "Y": (bandInfo["Intercept"] + bandWidth) * 100}


    #force within the chart bounds (or else the title will not display correctly)
    y:float = (math.log10(x) * bandInfo["Slope"] + bandInfo["Intercept"] + bandWidth)* 100
    x = 10**((y/100 - bandInfo["Intercept"] - bandWidth)/bandInfo["Slope"])

    return {"X": x, "Y": y}

def _CalcPoint (x:float, bandWidth:float, minX: float, maxX: float, minY:float, maxY:float, bandInfo):
    if bandInfo["Slope"] == 0:
        x = min (max (x, minX), maxX)
        return {"X": x, "Y": (bandInfo["Intercept"] + bandWidth) * 100}
    elif (math.isnan (bandInfo["Slope"])):
        x = min (max (x, minX), maxX)
        if (x == minX):
            y = minY + bandWidth
        else :
            y = maxY + bandWidth
        return {"X": x, "Y": (bandInfo["Intercept"] + bandWidth) * 100}


    #force within the chart bounds (or else the title will not display correctly)
    y:float = (math.log10(x) * bandInfo["Slope"] + bandInfo["Intercept"] + bandWidth)* 100
    if (y < minY):
        y = minY
        x = 10**((y/100 - bandInfo["Intercept"] - bandWidth)/bandInfo["Slope"])
    elif (y > maxY):
        y = maxY
        x = 10**((y/100 - bandInfo["Intercept"] - bandWidth)/bandInfo["Slope"])

    return {"X": x, "Y": y}


def _CalcLine(percent: float, minX: float, maxX: float, minY:float, maxY:float,bandInfo):
    bandWidth = bandInfo["BandWidth"]
    if percent < 50:
        bandWidth = -1 * bandWidth
    points = []
    original_points = []
    original_points.append(_CalcOriginalPoint (minX, bandWidth, minX, maxX, minY, maxY, bandInfo))
    points.append(_CalcPoint (minX, bandWidth, minX, maxX, minY, maxY, bandInfo))
    original_points.append(_CalcOriginalPoint (maxX, bandWidth, minX, maxX, minY, maxY, bandInfo))
    points.append(_CalcPoint (maxX, bandWidth, minX, maxX, minY, maxY, bandInfo))
    x_pts = []
    y_pts = []
    x_pts_org = []
    y_pts_org = []
    for point in points:
        x_pts.append(point["X"])
        y_pts.append(point["Y"])
    for point in original_points:
        x_pts_org.append(point["X"])
        y_pts_org.append(point["Y"])
    return x_pts,y_pts,x_pts_org,y_pts_org
	
	
import plotly.graph_objects as go
from plotly.graph_objs import *
import math
x_axis = df["RMS"]
y_axis = df["AROS"]
size = df["Sales"]

layout = Layout(
    width = 1000,
    height = 800,
    plot_bgcolor='#ffffff',
    title={
            "text": "North America Confectionary market companies<br><span style=\"font-family:Courier New;font-size: 20px;color:blue;\">2002-2019 Average</span>",
            "x": 0.5
        }
)
fig = go.Figure(data=[go.Scatter(
    x=x_axis,
    y=y_axis,
    mode='markers',
    marker=dict(
        size=df["Sales"],
        sizemode='area',
        sizeref=2.*max(size)/(100.**2),
        sizemin=4 ,color=['rgb(93, 164, 214)', 'rgb(255, 144, 14)']
    ),text=df["Series Label"],showlegend=False,hoverinfo='skip',fillpattern=dict(shape=['+'])
)],layout=layout)

x_pts,y_pts,x_pts_org,y_pts_org = _CalcLine(80.0, 0.1, 10, 0, 60, bandInfo)
fig.add_trace(
    go.Scatter(
        x=x_pts,
        y=y_pts,mode='lines+text',showlegend=False
    ))

# p = y_pts[1] - y_pts[0]
# q = x_pts[0] - x_pts[1]
# r = p*(x_pts[0]) + q*(y_pts[0])
# x_point = (r - (q*30))/p

slope_80 = (y_pts_org[1] - y_pts_org[0])/(x_pts_org[1] - x_pts_org[0] )
angle_in_radians = math.atan(slope_80)
angle_in_degrees = math.degrees(angle_in_radians-((3*math.pi)/4))
# print(math.log10(max(x_pts)-min(x_pts)))
# print((max(y_pts)-min(y_pts)))
# fig.add_annotation(x = math.log10(x_point) , y = 30, text = "80th Percentile", 
#                    showarrow=False,textangle=angle_in_degrees, )
fig.add_annotation(x = math.log10(max(x_pts)-min(x_pts)) , y = max(y_pts)*0.95, text = "80th Percentile", 
                   showarrow=False,textangle=angle_in_degrees, xref='x',yref='y')

print(x_pts,y_pts)
x_pts,y_pts,x_pts_org,y_pts_org = _CalcLine(20.0, 0.1, 10, 0, 60, bandInfo)
fig.add_trace(
    go.Scatter(
        x=x_pts,
        y=y_pts,mode='lines+text',showlegend=False
    ))
print(x_pts,y_pts)
fig.add_annotation(x = math.log10(max(x_pts)-min(x_pts)) , y = max(y_pts)*0.95, text = "20th Percentile",
                   showarrow=False,textangle=angle_in_degrees, xref='x',yref='y')
fig.update_layout(xaxis=dict(showgrid=False),
              yaxis=dict(showgrid=False)
)
fig.update_xaxes(type="log", title = "Relative Market Share (RMS)",range=[-1,1],tickvals=[0.1,1,2,3,4,5,6,7,8,9,10])
fig.update_yaxes(range=[0,60],title="Adjusted Return on Sales (AROS)")
fig.update_xaxes(showline=True, linewidth=1, linecolor='black', mirror=True,showticklabels = True)
fig.update_yaxes(showline=True, linewidth=1, linecolor='black', mirror=True,showticklabels = True,
      tickfont = dict(
      family = 'Old Standard TT, serif',
      size = 12,
      color = 'black'
      ),
      tickmode = 'linear',
      tick0 = 0.0,
      dtick = 10)
for row in df.itertuples(index=False):
    fig.add_annotation(
        x = math.log10(row[1]),
        y = row[2],
        xref="x",
        yref="y",
        text = row[0],
        align="center",
        showarrow=False
    )

fig.add_shape(
    xref = "paper", yref="paper",
    x0 = 1.01, y0 =0.01,type="circle",x1=1.08, y1 =0.10
)
fig.add_annotation(
    xref = "paper", yref="paper",
    x = 1.01+((1.08-1.01)/2)+0.03, y =0.01 + ((0.10-0.01)/2)-0.03, text ="$35k<br>Revenue",showarrow = False,align="center"
)
# fig.add_annotation(
#     xref="paper", yref="paper",
#     x=math.log10(10), y=0.1,width = 100,
#     height = 20,
#     text = "Legend Bubble",showarrow=False,bordercolor ="Black"
# )
fig.show()

shubhamgupta568 avatar Jun 16 '22 10:06 shubhamgupta568

Can you please provide a more minimal example of the problem, and confirm that you're running the latest version of plotly (5.8) and that you've looked at https://plotly.com/python/troubleshooting/ ?

nicolaskruchten avatar Jun 16 '22 14:06 nicolaskruchten

@nicolaskruchten I am using plotly 5.8.2. Please find below the minimal example where its not working.

import plotly.graph_objects as go result = [] trace = go.Scatter(x=[0], y=[2],marker=dict(size=100), fill="toself", fillpattern_shape="/") result.append(trace) fig = go.Figure(data=result) fig.show()

shubhamgupta568 avatar Jun 17 '22 04:06 shubhamgupta568

Right, the fill pattern is applied to the area, not the markers. The way to distinguish markers from each other other than color and size is to use symbol

nicolaskruchten avatar Jun 17 '22 11:06 nicolaskruchten