I am struggling to get a customized hovertemplate on plotly parcats chart - plotly-python

So I tried to put hovertemplate inside go.Parcats but not sure which way to put it. I want something like when you hover on any line it shuold show the custom discription like names of attributes and count and percentage on hover.
Also is there any wat to blank out those labels at the bottom of the chart so that it looks less busy and nicer but also when you hover on it shuold show up details. I know it's too much of customization but hoping it's doable.
dimensions.append(dict(values = df[dim], label = dim, categoryarray = df[dim].unique(), categoryorder = 'array', ticktext = slabel))
fig = go.Figure(data = [go.Parcats(dimensions= dimensions,
line = {'color': color, 'colorscale':colorscale,},
)]
)

Related

mpandroidchart the dot's color doesn't change in scatter chart

I'm using MPandroidchart to draw scatter chart.
I want to make a scatter chart that has a base line.
If value over the base line, in my case 0.2, its color change to red.
If not, it color is blue.
This is the codes i did.
if (d>=0.5)
{
colors.add(getBaseContext().getResources().getColor(R.color.color_red));
} else
{
colors.add(getBaseContext().getResources().getColor(R.color.color_blue));
}
value1.add(new Entry(k,d));
But it didn't change dot's color, but change squre's color next to label
I have tried
1)
if(index == specificIndex) colors.add(Color);
else colors.add(NormalColor);
2)
ArrayList<Integer> color = new ArrayList<>();
if (YOUR_CONDITION) {
color.add(ColorTemplate.rgb("#f8bf94"));
yVals1.add(new Entry(VALUE, COUNTER));
} else {
color.add(ColorTemplate.rgb("#e0e0e0"));
yVals1.add(new Entry(VALUE, COUNTER));
}
set1.setColors(color);
3)
color.add(Color.RED);
color.add(context.getResources().getColor(R.color.your_defined_color_in_colors_xml));
dataSet.setCircleColors(color);
But it didn't work.
How can i solve this?
After spending hours with this same issue, I have realized that it is the result of a bug in the MPAndroidChart project.
Basically, in the ScatterChartRenderer, the colors array is being treated such that only even colors are being applied to data points. For each Entry i, the color is set to colors[i / 2] meaning that the same color will be applied to two different entries due to integer division. This results in only half of the colors array being used.
To resolve this issue quickly, my solution was to add each entry to the DataSet twice. This means two points are drawn on top of each other, but both have the proper color set.
I am submitting a pull request to hopefully fix this issue in the next release, but for now this quick hack should work.

Shiny Dashboard Inputs inside MenuItems Problems

I am new to shiny dashboards and I am trying my hand at making a simple dashboard. I am trying to put together a dashboard that will basically go through different clustering algorithms and show how they work.
I have a menu item for the overall branching topic, and then input items within those menus that specify the parameters for the clustering algorithms.
My issue is I cannot get any output on my screen. I cannot render plots of even see the title for the boxes that I placed inside the tabItems. This seems to happen when I place a sub-item inside one of my menu items. I am not sure why.
Attached is my ui.R script and server.R script.
ui.R file:
server.R file:
Any help with this matter would be much appreciated.
So, as far as I can see, the problem is due to the fact that you placed the radioButtons within the menuItem. If you want to only show the radioButtons when the tab kclustering is active, you need to wrap radioButtons in a conditionalPanel. It would look something like that:
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Bla"),
dashboardSidebar(
sidebarMenu(
id = "tabs",
menuItem(
"K-clustering",
tabName = "kclustering",
icon = icon("cogs")),
conditionalPanel(
"input.tabs == 'kclustering'",
radioButtons("technique", "Technique Choice",
c("K-Means" = "kmeans",
"K-Medians" = "kmedians",
"K-Medoids" = "kmedoids"),
select = "kmedians")
),
menuItem("DBSCAN", tabName = "dbscan")
)
),
dashboardBody(
tabItems(
tabItem("kclustering",
fluidRow(
box(plotOutput("step1"))
))
)
))
server <- function(input, output) {
output$step1 <- renderPlot({
hist(rnorm(5000))
})
}
runApp(shinyApp(ui, server))
In this case, it's important to set the id argument of the sidebarMenu object to be able to formulate your condition.
Bottom line is: don't put your radioButtons, sliderInput and textInput inside the menuItem objects but in the sidebarMenu object itself.

ios-charts How to invalidate/redraw after setting data

See Updates At Bottom (4/30/2015)
I'm implementing a Pie Chart in Swift for iOS using ios-charts, and have chosen to customize the legend. Of note, the chart is displayed within a cell of a UICollectionView. The problem is that on first display, the custom legend content is not being displayed. Instead, I get legend content generated from the data.
If I scroll the view off-screen, and then scroll it back onto the screen, the proper custom legend is displayed. So, I'm guessing that I need to force a redraw/relayout/re-something after setting my custom legend. I haven't figured out how to do that. Does anyone have an idea? Am I completely missing something? Thanks!
Chart on initial display - data-generated (wrong) legend
Chart after scrolling off and back onto the screen - (proper legend)
Here's my code for drawing this chart:
func initChart(pieChart: PieChartView) {
numFormatter.maximumFractionDigits = 0
pieChart.backgroundColor = UIColor.whiteColor()
pieChart.usePercentValuesEnabled = false
pieChart.drawHoleEnabled = true
pieChart.holeTransparent = true
pieChart.descriptionText = ""
pieChart.centerText = "30%\nComplete"
pieChart.data = getMyData()
// Setting custom legend info, called AFTER setting data
pieChart.legend.position = ChartLegend.ChartLegendPosition.LeftOfChartCenter
pieChart.legend.colors = [clrGreenDk, clrGold, clrBlue]
pieChart.legend.labels = ["Complete","Enrolled","Future"]
pieChart.legend.enabled = true
}
func getMyData() -> ChartData {
var xVals = ["Q201","R202","S203","T204","U205", "V206"]
var courses: [ChartDataEntry] = []
courses.append(ChartDataEntry(value: 3, xIndex: 0))
courses.append(ChartDataEntry(value: 3, xIndex: 1))
courses.append(ChartDataEntry(value: 4, xIndex: 2))
courses.append(ChartDataEntry(value: 4, xIndex: 3))
courses.append(ChartDataEntry(value: 3, xIndex: 4))
courses.append(ChartDataEntry(value: 3, xIndex: 5))
let dsColors = [clrGreenDk, clrGreenDk, clrBlue, clrBlue, clrGold, clrGold]
let pcds = PieChartDataSet(yVals: courses, label: "")
pcds.sliceSpace = CGFloat(4)
pcds.colors = dsColors
pcds.valueFont = labelFont!
pcds.valueFormatter = numFormatter
pcds.valueTextColor = UIColor.whiteColor()
return ChartData(xVals: xVals, dataSet: pcds)
}
Update 4/30/2015
Based on discussion with author of MPAndroidChart (on which ios-charts is based), it appears there is not a point in the chart display lifecycle where one can override the legend on "first draw". Basically, the chart is rendered when it is created, no matter what. If you set data on the chart, the chart uses that data to create the legend and then renders. It isn't possible to change the legend between the point of setting data, and the point of chart rendering.
setNeedsDisplay()
Potentially, one can wait for the chart to render, update the legend, and then call chart.setNeedsDisplay() to signal the chart to redraw. Sadly, there's a timing problem with this. If you call this method immediately after rendering the chart, it either doesn't fire or (more likely) it fires too soon and is effectively ignored. In my code, placing this call within viewDidLoad or viewDidAppear had no effect. However...
Building the same chart in Java for Android (using MPAndroidChart) results in the same issue. After messing around for a bit, I noted that if I called the chart.invalidate() after a delay (using Handler.postDelayed()), it would fire properly. It turns out a similar approach works for ios-charts on iOS.
If one uses GCD to delay the call to setNeedsDisplay(), for even a few milliseconds after the rendering, it seems to do the trick. I've added the following code immediately after initializing the chart's view in my ViewController ("cell" is the UICollectionViewCell containing the chart view):
delay(0.05) {
cell.pieChartView.legend.colors = [self.clrGreenDk, self.clrGold, self.clrBlue]
cell.pieChartView.legend.labels = ["Complete","Enrolled","Future"]
// Re-calc legend dimensions for proper position (Added 5/2/2015)
cell.pieChartView.legend.calculateDimensions(cell.pieChartView.labelFont!)
cell.pieChartView.setNeedsDisplay()
}
Using the awesome "delay" method from this SO post: https://stackoverflow.com/a/24318861
Obviously, this is a nasty hack, but it seems to do the trick. I'm not sure I like the idea of using this hack in production, though.
For any Android folk who stumble on this post:
The following code achieves the same effect using MPAndroidChart:
// Inside onCreate()
pie = (PieChart) findViewById(R.id.chart1);
configPieChart(pie);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
String[] legLabels = new String[]{"Complete","Enrolled","Future"};
ArrayList<Integer> legColors = new ArrayList<Integer>();
legColors.add(blue);
legColors.add(gold);
legColors.add(green);
pie.getLegend().setPosition(Legend.LegendPosition.LEFT_OF_CHART_CENTER);
pie.getLegend().setColors(legColors);
pie.getLegend().setLabels(legLabels);
pie.invalidate();
}
}, 20);
I am the author of ios-charts, and we're working on features for customizing the legend data, without those "hacks".
In the latest commits to ios-charts, you can already see extraLabels and extraColors properties that add extra lines to the legend, and a setLegend function that allows you to set a custom data entirely.
This will soon be added to the Android version as well.
Enjoy :-)

Fix series order

I am producing a graph using the following code:
var svg = dimple.newSvg("#p_m", 1200, 200+(data.f_c_c*20));
var chrt_participants = new dimple.chart(svg, data.result);
chrt_participants.setBounds(200, 50, 900, 100+(data.f_c_c*20));
var y = chrt_participants.addCategoryAxis("y", ["title", "name"]);
var x = chrt_participants.addLogAxis("x", "Activity");
var s = chrt_participants.addSeries(["cid_id","cid","action"], dimple.plot.bar);
chrt_participants.addLegend(800, 0, 400, 40, "left");
chrt_participants.draw();
It draws the following graph:
Everything is as expected, except that the series (the coloured chunks of the bars) don't seem to be put in any particular order. As you can see, for two bars, for some reason unbeknownst to me, the red value is placed before the blue.
Is there a way to fix the order of the series?
The default order is descending by value but you can easily override using series.addOrderRule(). The documentation explains how:
https://github.com/PMSI-AlignAlytics/dimple/wiki/dimple.series#addOrderRule
On a side issue, be careful using a log axis for a stacked bar, it's very misleading. It's not immediately apparent that red and blue have about a 50/50 split of bars. You might be better using a grouped bar instead so that both categories receive comparable scaling.

react on events generated by chaco tools: how to get values out of a chaco tool when an event is fired ?

actually this should be a pretty simple question, but I am experiencing the quite steep learning curve of chaco and traits...
I am currently writing an application to plot a medical image using chaco and traits and I simply want to pick a pixel location from the image and use this pixel location to do evaluations on an image stack. So I started to write my own Chaco Tool that reacts on mouse clicks on an imageplot.
This works fine so far. When I click on the imageplot I can see the mouse coordinates WITHIN the Tool (a custom made PixelPickerTool). However, as I want to use this coordinate value outside the tool my question would be: How can I hand the coordinates over to another object or variable OUTSIDE the Tool when an event is fired.
To illustrate what I want to do I attached the main structure of the two classes I am Writing:
class PixelPickerTool(BaseTool):
'''Pick a Pixel coordinate from an image'''
ImageCoordinates = [0,0]
def normal_left_down(self, event):
print "Mouse:", event.x, event.y,
click_x, click_y = self.component.map_data((event.x, event.y))
img_x = int(click_x)
img_y = int(click_y)
coord = [img_x, img_y]
if ( (img_x > self.ImageSizeX) or (img_x < 0) ):
coord = [0,0]
if ( (img_y > self.ImageSizeY) or (img_y < 0) ):
coord = [0,0]
print coord
# this print gives out the coordinates of the pixel that was clicked - this works fine...
# so inside the picker too I can get the coordinates
# but how can I use the coordinates outside this tool ?
class ImagePlot(HasTraits):
# create simple chaco plot of 2D numpy image array, with a simple interactor (PixelPickerTool)
plot = Instance(Plot)
string = String("hallo")
picker = Instance(PixelPickerTool)
traits_view = View(
Item('plot', editor=ComponentEditor(), show_label=False,width=500, height=500, resizable=False),
Item('string', show_label=False, springy=True, width=300, height=20, resizable=False),
title="")
def __init__(self, numpyImage):
super(ImagePlot, self).__init__()
npImage = np.flipud(np.transpose(numpyImage))
plotdata = ArrayPlotData(imagedata = npImage)
plot = Plot(plotdata)
plot.img_plot("imagedata", colormap=gray)
self.plot = plot
# Bild Nullpunkt ist oben links!
self.plot.default_origin = 'top left'
pixelPicker = PixelPickerTool(plot)
self.picker = pixelPicker
plot.tools.append(pixelPicker)
I want to use the coordinates that are measured by the PixelPickerTool somewhere in this ImagePlot class. E.g. by handing them over to another Object like MyImageSeries.setCoordinate(xy_coordinateFromPickerTool)
So how can I hand over the pixel coordinates from PickerTool to some member variable in this class when an event is fired ?
Maybe something like this: self.PixelCoordinates = picker.getPixelCoordinates() could work ?
But how do I know then, when the on_normal_left_down function was executed in the picker ?
In the end I want to hand the coordinates over to another class which hold more images to process the images and do a fit at the pixel position determined in the ImagePlot.
I tried to use something like "_picker_changed" in my imagePlot class to detect if an event has been fired in the PickerTool, but this didn't detect event firing. So maybe I am doing something wrong...
Can anybody tell me how to get events and associated variables out of this picker tool ?
Cheers,
Andre
"But how do I know then, when the on_normal_left_down function was executed in the picker?"
There are several ways you could probably do this, but one way would be to simply do exactly what you are asking and fire an event that you define explicitly.
for instance:
from traits.api import Event
class PickerTool(BaseTool):
last_coords = SomeTrait
i_fired = Event
def normal_left_down(self,event):
# do whatever necessary processing
self.last_coords = do_some_stuff(event.some_attribute)
# now notify your parent
self.i_fired = True
and then listen to plot.picker.i_fired from wherever you want to display, and look in plot.picker.last_coords for the saved state.
Another thing you can do that may be simpler if what you want to do with these coordinates is very straightforward, is just pass on intialization the data structures the picker needs to interact with (or get them with a chain of calls to self.parent) and do your work directly inside the picker.